【问题标题】:JUnit how to test multiple functionsJUnit如何测试多个功能
【发布时间】:2025-12-31 14:35:10
【问题描述】:

我的问题是:如果我有一个测试方法,让我们说一个代表一个人的对象的构造函数: public void Person(String name){this.name = name;},创建一个测试用例是不是很傻:

public class PersonTest {

@Test
public void testPerson() throws myException{
    // First thing I want to test
    try {
        new Person("name to looooooooooooooong");
        fail("This test was supposed to throw an exception: name too long");
    } catch (Exception e) {
        if (e instanceof myException)
            assertEquals("MSG: name not valid!", "Name not valid", e.getMessage());
    }
    //Second thing I want to test
    try {
        new Person("name to short");
        fail("This test was supposed to throw an exception: name too short");
    } catch (Exception e) {
        if (e instanceof myException)
            assertEquals("MSG: name not valid!", "Name not valid", e.getMessage());
    }
    //Oter things I want to test ...
}

或者我应该为每个对象创建一个测试套件,并为每个要测试的方法创建一个测试用例?但是如果我想测试一个方法的多个参数怎么办?我应该为每个案例编写一个测试用例吗?喜欢:

  • 一个名称太长的测试用例
  • 一个名称太短的测试用例
  • 一个包含数字名称的测试用例 等等?

【问题讨论】:

  • 最佳实践是为关于生产代码行为的每一个假设编写一个测试用例。除此之外:检查构造函数中名称的长度等业务规则可能为时已晚......

标签: java unit-testing testing junit


【解决方案1】:

关于构造函数..如果有可能根据输入抛出异常,那么对此进行测试就可以了。

一般来说,如果有任何认为重要的逻辑,那么您应该选择对这些代码部分进行单元测试。你必须很聪明,但不要测试太多,因为如果你得到超过 60/70% 的覆盖率,这意味着你已经测试了最重要的逻辑,你将达到收益递减的地步,因为测试更多意味着更多比实际收益更浪费时间。

关于方法:

一个名字太长的测试用例

一个名字太短的测试用例

包含数字等名称的测试用例?

这听起来不错,因为您希望您的测试涵盖您的方法中的一条逻辑路径.. 理想情况下不要更多。如果你确实开始测试更多的东西,那么你最终会得到很多难以调试、理解和维护的臃肿测试用例。

具有一/两个公共方法的小类,以及一套专门的测试将是理想的。

要记住的另一件事是,对于每个测试用例,尽可能对其进行参数化,以便为每个测试尽可能多地压缩可能性。

我强烈建议使用像 :Junit Data Provider 这样的项目来编写您的参数化案例。我已经使用它几年了,它比内置的 junit 参数化(如果你真的说有的话)更容易。

【讨论】:

    【解决方案2】:

    在 JUnit 中有一个很好的测试异常的工具:

     @Rule
     public ExpectedException thrown= ExpectedException.none();
    
     @Test
     public void throwsExceptionWithSpecificType() {
         thrown.expect(myException.class);
         thrown.expectMessage("Name not valid");
         new Person("name to looooooooooooooong");
     }
    

    【讨论】:

      【解决方案3】:

      “大”方法的测试看起来像集成测试,可以模拟较小的方法。

      如果您可以将“大”方法分成五个孤立的方法,那么“大”方法可以进一步划分为独立方法的语义/上下文意义组。

      然后,您可以为“大”方法模拟更大的隔离方法分组。

      【讨论】:

        【解决方案4】:

        它是参数化的完美案例。创建一个测试并将所有条件作为参数对象传递。

        参考:https://github.com/junit-team/junit4/wiki/parameterized-tests

        【讨论】: