为什么我的模拟测试总是传递给返回null但必须返回String的方法

时间:2017-11-24 19:32:59

标签: java unit-testing testing mocking mockito

我正在测试以检查方法是否返回正确的字符串。但即使方法返回null,测试也会通过!为什么会这样?如何正确地编写测试? 谢谢!

// TestMyObj.java: My test class
public class TestMyObj {
    @InjectMocks
    private MyClass myClass;

    @Mock
    TestObj testObj;

    private final String test = "test";

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);  // or use mockito runner
    }

    @Test
    public void test() {
        when(testObj.get()).thenReturn(test);
        Assert.assertTrue(myClass.get().equals(test));
        verify(testObj).get();
    }
}

// MyClass.java: Class which uses my object
public class MyClass {
    private TestObj testObj;

    public MyClass() {}
    public MyClass(TestObj testObj) { this.testObj = testObj; }
    String get() { return testObj.get(); }
}

// TestObj.java: My testing object 
public class TestObj {
    String get() { return null; }
}

2 个答案:

答案 0 :(得分:2)

myClass.get()返回testObj.get();与此同时,when(...)指示您testObj.get()返回test

所以myClass.get()基本上等同于test,而Assert.assertTrue(myClass.get().equals(test))缩减为Assert.assertTrue(test.equals(test)),当test不是null时,null断言正常在你的情况下它不是Assert.assertTrue(expected.equals(actual));

顺便说一句,而不是

Assert.assertEquals(expected, actual);

要好得多
@Test
public void test() {
    when(testObj.get()).thenReturn("test");
    assertEquals("test", myClass.get());
    verify(testObj).get();
}

它将为您提供有关失败的诊断消息,您将从中看到预期的值以及实际给予第二个参数的值。

所以我会重写像

这样的测试
MyClass

这似乎有道理:我们正在测试testObj正确调用其协作者test并将其返回值返回给我们。

使用常量而不是test变量似乎是正确的。首先,由于常数用于两个相邻的行,因此我没有出现任何问题,我在一个地方改变了我的常数而忘了在另一个地方做这个问题。第二,现在没有间接级别(使用var term = 'apple orange grape fruit'; 变量引入),因此代码更容易理解。

答案 1 :(得分:2)

正如其他人所解释的那样 - 首先仔细阅读你正在使用的概念。

关键在于:您嘲笑您的测试类的实例。因此,返回null的该方法的实际实现根本不重要。因为您创建了一个模拟对象并指示Mockito在调用get()时返回非null值。因此,返回null的实际方法体永远不会在您向我们显示的代码中执行。

这就是全部。