例外:mockito想要但未被调用,实际上与这个模拟没有交互

时间:2013-12-12 18:58:47

标签: java unit-testing mockito

我有界面

Interface MyInterface {
  myMethodToBeVerified (String, String);
}

接口的实现是

class MyClassToBeTested implements MyInterface {
   myMethodToBeVerified(String, String) {
    …….
   }
}

我有另一个班级

class MyClass {
    MyInterface myObj = new MyClassToBeTested();
    public void abc(){
         myObj.myMethodToBeVerified (new String(“a”), new String(“b”));
    }

}

我正在尝试为MyClass编写JUnit。我做完了

class MyClassTest {
    MyClass myClass = new MyClass();

    @Mock
    MyInterface myInterface;

    testAbc(){
         myClass.abc();
         verify(myInterface).myMethodToBeVerified(new String(“a”), new String(“b”));
    }
}

但我得到 mockito但未被调用,实际上在验证调用时与此模拟之间没有任何交互。

任何人都可以建议一些解决方案。

4 个答案:

答案 0 :(得分:11)

你需要在你正在测试的类中注入mock。此刻,您正在与真实对象进行交互,而不是与模拟对象进行交互。您可以通过以下方式修复代码:

void testAbc(){
     myClass.myObj = myInteface;
     myClass.abc();
     verify(myInterface).myMethodToBeVerified(new String(“a”), new String(“b”));
}

虽然将所有初始化代码提取到@Before

是一个更明智的选择
@Before
void setUp(){
     myClass = new myClass();
     myClass.myObj = myInteface;
}

@Test
void testAbc(){
     myClass.abc();
     verify(myInterface).myMethodToBeVerified(new String(“a”), new String(“b”));
}

答案 1 :(得分:7)

您的班级MyClass会创建一个新的MyClassToBeTested,而不是使用您的模拟。 My article on the Mockito wiki描述了两种处理此问题的方法。

答案 2 :(得分:4)

@ Jk1的答案很好,但Mockito还允许使用注释进行更简洁的注射:

@InjectMocks MyClass myClass; //@InjectMocks automatically instantiates too
@Mock MyInterface myInterface

但无论您使用哪种方法,注释都不会被处理(甚至不是@Mock),除非您以某种方式调用静态MockitoAnnotation.initMocks()或使用@RunWith(MockitoJUnitRunner.class)注释该类。

答案 3 :(得分:1)

@ jk1答案是完美的,因为@igor Ganapolsky问道,为什么我们不能在这里使用Mockito.mock?我发布了这个答案。

为此,我们为myobj提供了一个setter方法,并使用mocked对象设置myobj值。

class MyClass {
    MyInterface myObj;

    public void abc() {
        myObj.myMethodToBeVerified (new String("a"), new String("b"));
    }

    public void setMyObj(MyInterface obj)
    {
        this.myObj=obj;
    }
}

在我们的Test类中,我们必须编写下面的代码

class MyClassTest {

MyClass myClass = new MyClass();

    @Mock
    MyInterface myInterface;

    @test
    testAbc() {
        myclass.setMyObj(myInterface); //it is good to have in @before method
        myClass.abc();
        verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
     }
}