2016-08-09 4 views
4

Я использую Mockito для тестирования методов в моем приложении Java.Mockto: как проверить, что был вызван конструктор?

Как я могу проверить, что конструктор называется одним?

Я пытаюсь сделать проверить похожее на это:

verify(myclass, times(1)).doSomething(anotherObject); 

Но я не могу проверить, конструктор был вызван, поскольку он не имеет метод, аналогичный, например, doSomething()

+0

Ум, вы не можете получить объект, если вы его не называете его конструктором; это языковая функция. –

+1

, пожалуйста, объясните, что вы имеете в виду. – java123999

+0

Вы должны описать, что именно вы пытаетесь протестировать, что заставило вас подумать, что вам нужно высмеять конструктор. Я не удивлюсь, если в этом нет никакой реальной необходимости. –

ответ

8

Это не может быть сделано с помощью Mockito, поскольку создаваемый объект не является издеваемым объектом. Это также означает, что вы не сможете ничего проверить на этом новом объекте.

Я работал над этим сценарием в прошлом, используя Factory для создания объекта, а не для его создания. Затем вы можете издеваться над Factory, чтобы вернуть объект, необходимый для вашего теста.

Независимо от того, счастливы ли вы изменить свой дизайн в соответствии с вашими испытаниями, зависит от вас!

+0

Это кажется лучшим решением. Взгляните на использование класса Factory в будущем, чтобы решить эту проблему. – java123999

+0

Представляем фабрику, чтобы обойти ограничение в насмешливой библиотеке ... это, очевидно, не очень хорошее решение. Вместо этого я бы предложил избежать предполагаемой необходимости издеваться над созданным классом из SUT. Как правило, лучший тест без насмешивания возможен. –

0

Конструктор не возвращает объект, если он не прошел ... и если он не работает, программа, скорее всего, сбой.

Tough я полагаю, это будет сделать это:

Object obj = null; 

obj = new Object(); 

if (obj == null) { 
    //... Didn't Work 
} else { 
    //... Worked 
} 
+3

OP не спрашивает, как проверить, работает ли конструктор, но как проверить, действительно ли какой-либо другой код вызывает конструктор. –

1

verify() метод ждет издевались объекта (уже созданный объект). И constructor не может быть вызван на created object.

1

Это не возможно с помощью Mockito и звучит как плохой дизайн.

Вы можете использовать заводскую установку и передать ее проверяемому объекту. После этого вы можете легко издеваться над фабрикой и проверить, вызван ли ее метод создания.

Прямое создание объектов в коде, вы делаете жесткую зависимость от конкретных реализаций, что делает код более сложным, а иногда и невозможным для модульного тестирования. Это рассматривается с помощью инъекции зависимостей (DI) и инверсии управления (IoC).

0

Вы не сможете издеваться над конструктором с помощью mockito, но используя powermockito, вы должны быть в состоянии проверить его. Настройка будет что-то вроде этого

public class MyClass{ 

    public MyClass(String name){} 

    public void doSomethingUseFul(){ 
     //....... 
    } 

} 

public class Helper { 

    public void goHelp(){ 
     new MyClass("apple").doSomethingUseFul(); 
    } 

} 

// Mock

@RunWith(PowerMockRunner.class) 
    @PrepareForTest(MyClass.class) 
    public class MockMyClass { 
    @InjectMocks 
    private Helper helper; 

     @Test 
     public void testDoSomethingUseFul() { 
      MyClass c = mock(MyClass.class); 
      doNothing().when(c).doSomethingUseFul(); 
      PowerMockito.whenNew(MyClass. class).withArguments(anyString()).thenReturn(c); 
      helper.goHelp(); 
      verifyNew(MyClass.class).withArguments(anyString()) 


     } 
    } 
8

Вы можете сделать это с Mockito и PowerMockito.

Скажем, у вас есть ClassUnderTest с конструктором

public class ClassUnderTest { 
    String name; 
    boolean condition; 

    public ClassUnderTest(String name, boolean condition) { 
     this.name = name; 
     this.condition = condition; 
     init(); 
    } 

    ... 
} 

И еще один класс, который вызывает этот конструктор

public class MyClass { 

    public MyClass() { } 

    public void createCUTInstance() { 
     // ... 
     ClassUnderTest cut = new ClassUnderTest("abc", true); 
     // ... 
    } 

    ... 
} 

В классе Test мы могли бы ...

(1) использовать PowerMockRunner и ссылаются как целевые классы выше в PrepareForTest аннотации:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ ClassUnderTest.class, MyClass.class }) 
public class TestClass { 

(2) перехватывают конструктора, чтобы вернуть макет объекта:

@Before 
public void setup() { 
    ClassUnderTest cutMock = Mockito.mock(ClassUnderTest.class); 
    PowerMockito.whenNew(ClassUnderTest.class) 
       .withArguments(Matchers.anyString(), Matchers.anyBoolean()) 
       .thenReturn(cutMock); 
} 

(3) Подтвердить вызов конструктора:

@Test 
public void testMethod() { 
    // prepare 
    MyClasss myClass = new MyClass(); 

    // execute 
    myClass.createCUTInstance(); 

    // checks if the constructor has been called once and with the expected argument values: 
    String name = "abc"; 
    String condition = true; 
    PowerMockito.verifyNew(ClassUnderTest.class).withArguments(name, condition); 
} 
+0

Я думаю, что последовательность последних двух строк в вашем методе testMethod() должна меняться. например: new ClassUnderTest (имя, условие); PowerMockito.verifyNew (ClassUnderTest.class); –

+0

@WillieZ, большое спасибо за то, что вы обратили мое внимание на этот метод тестирования! По правде говоря, эта предыдущая команда не нужна. Первоначальная идея состояла в том, чтобы протестировать вызов конструктора с определенными значениями аргументов в методе, вызванном на этапе выполнения. Я только что переписал код, чтобы выразить свое первоначальное намерение. Надеюсь, теперь это становится яснее. –

Смежные вопросы