6

我正在使用 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 方法的最佳方法是什么?

非常感谢你....

4

3 回答 3

4

我看着你的ClassA,我想知道如何bList设置任何东西。现在,除了 null 之外没有其他办法,这意味着getStatus每次都会抛出一个空指针异常。

您的问题是您正在考虑如何测试方法而不是考虑如何测试行为。这是一个问题的一个原因是你的类必须以某种方式适应你的应用程序的其余部分。为了确保它做到这一点,它需要某些行为,而不是每个方法中的某些细节。所以唯一有意义的测试是检查行为。

也许更阴险的是,测试单个方法会使您专注于您实际编写的代码。如果您在编写测试时正在查看代码,那么您的测试将成为一个自我实现的预言。你可能错过了你的班级需要提供的一整套行为;但是如果你只测试你的班级确实提供的行为,你永远不会知道。

所以,回到手头的问题。我看到了你的班级可能会实现的四种,也许是五种行为。也许还有更多 - 很难判断您是否只向我们展示代码而不是规范。你应该为每一个写一个测试。我坚信每个测试的名称应该描述行为,而不是反映测试使用的方法的名称。在这种情况下,我可能会选择这样的名称。

public void statusIsPassedWhenEveryTestPassed()
public void statusIsFailedWhenEveryTestFailed()
public void statusIsFailedWhenSomeTestsPassedSomeFailed()
public void statusIsPassedWhenNoTests()
public void statusIsPassedWhenTestsNotSet() // this one currently fails

在每个测试中,我会创建一个 的对象ClassA,然后做任何必须做的事情来设置bList对象内的 。最后,我会调用getStatus并断言返回值是我想要的。但重要的一点是,每个测试(最后一个除外)都使用不止一种方法ClassA,因此这些不是单独方法的测试。

于 2012-10-05T18:17:10.803 回答
0

您可以为受保护的对象提供设置器(或构造函数注入),然后在测试用例中扩展类以模拟对象,或者您可以尝试使用类似powermock的东西。您仍然需要提供一种方法来设置这些对象。

于 2012-10-05T16:37:35.463 回答
0

我想这取决于你如何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() {
     // ...
  }

}
于 2012-10-05T16:48:25.567 回答