2017-02-04 5 views
1

Я новичок в Mockito, пожалуйста, помогите в понимании базового.Метод mock не вызван - java

По моему мнению, код должен печатать 5, когда вызывается mocked.add(6,7), но метод add() не вызван, а код печатает 0 .. почему? любое решение для этого кода?

import org.mockito.Mockito; 

    import static org.mockito.Mockito.*; 


    class Calc{ 

     int add(int a,int b){ 
     System.out.println("add method called"); 
     return a+b; 
    } 

}

 class MockTest{ 
      public static void main(String[] args) { 
      Calc mocked=mock(Calc.class); 
      when(mocked.add(2,3)).thenReturn(5); 
      System.out.println(mocked.add(6,7)); 
     } 
     } 
+1

Ваш вопрос не имеет смысла для меня. Вы явно говорите mockito «когда аргументы 2 и 3, затем верните 5», а затем вы пройдете 6 и 7 ...почему mockito применяет это правило, если предварительные условия не выполняются? – Tom

ответ

1

Для того, чтобы получить результат 5, вы должны пройти точные Params, как при настройке when..then. В противном случае Mockito будет возвращать значение «по умолчанию» (которое 0 для целого:

Каких ценностей издеваются возвращают по умолчанию

Для того, чтобы быть прозрачными и ненавязчивыми все Mockito иронизирует по возврата по умолчанию «хорошим 'значения, например:.. нули, falseys, пустые коллекции или нули см Javadocs о гася видеть точно , что значения по умолчанию возвращается

Если вы хотите возвратить 5 для любого целого затем использовать.:

when(mocked.add(Mockito.any(Integer.class),Mockito.any(Integer.class))).thenReturn(5); 
0

«mock» - это просто пустой объект-пустышка, который имитирует поведение «реального» объекта. Если вы определяете поведение, подобное when(mocked.add(2,3)).thenReturn(5);, вы конкретно говорите этому макету, что делать, когда он получает эти точные значения.

mocked.add(6,7) вернется 0 в этот момент, так как вы не определили его поведение для тех значений и, следовательно, использует значение в по умолчанию. Поэтому, если вы хотите охватить все возможные входы, вы можете пойти с решением @MaciejKowalski и использовать общие шаблоны, такие как Mockito.any(Integer.class).

Тем не менее, я считаю, что непонятно, как правильно обрабатывать издевательства. Mocks - это способ предоставления внешних зависимостей системному тестированию без необходимости создания целого дерева зависимостей. Реальные методы внутри этого класса обычно не вызываются. Вот что значит when(mocked.add(2,3)).thenReturn(5);. Он сообщает макету behave как настоящая зависимость, фактически не имея ее под рукой.

Примером может выглядеть следующим образом:

public class TestClass { 
    private ExternalDependency dep; 
    public void setDep(ExternalDependency dep) { 
     this.dep = dep; 
    } 
    public int calculate() { 
     return 5 + dep.doStuff(); 
    } 
} 

public class ExternalDependency { 
    public int doStuff() { 
     return 3; 
    } 
} 

Теперь в тестовом коде вы можете использовать издевается, как это:

@Test 
public void should_use_external_dependency() { 
    // Aquire a mocked object of the class 
    ExternalDependency mockedDep = Mockito.mock(ExternalDependency.class); 
    // Define its behaviour 
    Mockito.when(mockedDep.doStuff()).thenReturn(20); 

    TestClass sut = new TestClass(); 
    sut.setDep(mockedDep); 

    // should return 25, since we've defined the mocks behaviour to return 20 
    Assert.assertEquals(25, sut.calculate()); 
} 

Если sut.calculate() вызывается метод в ExternalDependency не должно быть на самом деле вместо этого он делегирует вместо себя издевательский объект-заглушку. Но если вы хотите, чтобы вызвать реальный метод реального класса, вы могли бы использовать Spy вместо с Mockito.spy(ExternalDependency.class) или вы могли бы сделать это с when(mockedDep.doStuff()).thenCallRealMethod();

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