【问题标题】:Should all of my unit tests always pass when method is given bad input?当方法输入错误时,我的所有单元测试都应该通过吗?
【发布时间】:2018-03-12 02:43:22
【问题描述】:

我对测试驱动开发有点陌生,我正在尝试确定我的单元测试方法是否存在问题。
我有几个单元测试(我们称它们为 A 组)来测试我的方法的返回是否符合预期。
我还有一个单元测试“B”,其通过条件是当我的方法输入无效时抛出IllegalArgumentException
当方法输入无效时,A 组中的单元测试会失败,因为该方法需要有效输入才能正确返回。
如果我捕捉到异常,单元测试“B”将失败,但如果我没有捕捉到异常,则 A 组中的测试将失败。
以这种方式让单元测试失败是否可以,或者我可以以某种方式修改代码以使所有测试始终通过?
我做 TDD 错了吗?
为了更清楚,这是我的代码的一个概念:

public class Example{
    public static String method(String inputString, int value){
        if(badInput){
            throw new IllegalArgumentException();
        }
        //do some things to inputString
        return modifiedInputString;
    }
}

public class ExampleTests{
    @Test
    public void methodReturnsIllegalArgumentExceptionForBadInput(){
        assertThrows(IllegalArgumentException.class, ()->{Example.method(badInput,badValue);})
    }

    //"Group A" tests only pass with valid input. Bad input causes IllegalArgumentException
    @Test
    public void methodReturnsExpectedType(){
        assertTrue(actual == expected);
    }

    @Test
    public void methodReturnsExpectedValue(){
        assertTrue(actual == expected);
    }

    @Test
    public void methodReturnsExpectedStringFormat(){
        assertTrue(actual == expected);
    }
}

【问题讨论】:

  • 单元测试测试方法是否为特定输入产生特定输出。所以你应该有以下测试:通过输入A - 获得输出A1,通过输入B - 获得输出B1,通过无效输入 - 抛出异常E,通过另一个无效输入 - 抛出异常E1。因此,将无效输入传递给期望有效输入的测试不是一个合适的用例。
  • 谢谢你,这让我明白了。我想我的问题是我将有效或无效的输入传递给所有测试,不管他们在测试什么。

标签: java unit-testing junit tdd


【解决方案1】:

正如您在评论中正确指出的那样,问题在于测试设置过于广泛且测试过于隐含。

当测试在业务级别上是独立的时,它们的可读性会更高。通用测试设置应侧重于设置技术细节,但所有业务设置都应包含在每个测试本身内。

您的案例示例(概念示例,必须重新设计以匹配您的实施细节):

@Test
public void givenWhatever_whenDoingSomething_methodReturnsExpectedType(){
    given(someInputs);

    Type result = executeSut(); //rename executeSut to actual function under test name

    assertTrue(result == expected);
}

通过这种方式,只需查看测试,读者就知道正在测试什么场景。常见的测试设置和辅助功能(例如given)抽象出技术细节,因此读者不会在第一次检查时分心。如果他们感兴趣,细节总是可用的 - 但通常不太重要,可以隐藏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2014-07-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    相关资源
    最近更新 更多