我正在使用JUnit和Mockito来测试一些类。类本身从另一个类创建一个对象。一个名为testList的列表。这是我的代码:
public class A {
private List<B> bList;
//returns the bList
public List<B> getBList() {
return bList;
}
//checks the status by calling getStatus in class B
public Status getStatus() {
//status is an enum consists of PASSED and FAILED
Status finalStatus = Status.PASSED;
for (B be : this.getTestList()) {
if (be.getStatus() != Status.PASSED) {
finalStatus = Status.FAILED;
break;
}
}
return status;
}
}
public Class B {
private Status status = Status.FAILED;
public getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
在名为test的类中测试getStatus和getTestList方法的最佳方法是什么。
非常感谢。。。。
我查看了您的ClassA
,想知道bList
是如何设置为任何值的。现在,它不可能是null以外的任何东西,这意味着getStatus
每次都会抛出一个null指针异常。
您的问题是,您正在考虑如何测试方法,而不是考虑如何测试行为。这是一个问题的原因之一是,您的类必须以某种方式与应用程序的其余部分相适应。为了确保它做到这一点,它需要特定的行为,而不是每个方法中的特定细节。因此,唯一有意义的测试是检查行为。
也许更阴险的是,测试单个方法会让您专注于实际编写的代码。如果您在编写测试时查看代码,那么您的测试将成为一个自我实现的预言。你可能错过了要求你的班级提供的一整套行为;但是,如果您只测试类提供的行为,您将永远不会知道。
所以,回到手头的问题上来。我看到了四种,也许五种行为,你的班级可能会完成。也许还有更多——如果你只给我们看代码,而不给我们看规范,那就很难说了。你应该为每一个写一个测试。我坚信,每个测试的名称应该描述行为,而不是反映测试使用的方法的名称。在这种情况下,我可能会选择这样的名字。
public void statusIsPassedWhenEveryTestPassed()
public void statusIsFailedWhenEveryTestFailed()
public void statusIsFailedWhenSomeTestsPassedSomeFailed()
public void statusIsPassedWhenNoTests()
public void statusIsPassedWhenTestsNotSet() // this one currently fails
在每个测试中,我都会创建一个ClassA
的对象,然后做任何必须做的事情来设置对象中的bList
。最后,我将调用getStatus
并断言返回值是我想要的。但重要的一点是,每个测试(除了最后一个)都使用了不止一种ClassA
方法,因此这些不是单个方法的测试。
您可以为受保护的对象提供setter(或构造函数注入),然后在测试用例中扩展类以模拟对象,也可以尝试使用类似powermock的方法。您仍然需要提供一种方法来设置这些有问题的对象。
我想这取决于如何在单元测试中填充testList
。如果你有一个setter,那么你就不需要任何模拟框架
class TestTest {
Test test = new Test();
@Test void should_return_failed_if_a_single_test_failed() {
givenTestListWithOneFailedTest();
assertThat(test.getStatus(), is(Status.FAILED))
}
void givenTestListWithOneFailedTest() {
test.setTestList(createSomeTestListWithOnlyOneFailedTest());
}
@Test void should_return_passed_if_all_tests_passed() {
// ...
}
}