我正在测试以检查方法是否返回正确的字符串。但即使方法返回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; }
}
答案 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的实际方法体永远不会在您向我们显示的代码中执行。
这就是全部。