繁体   English   中英

单元测试,可以测试一种方法吗?

[英]Unit tests, can you test a single method?

我可能会问一些完全显而易见的问题。 我在编写单元测试方面经验不足,出现了以下问题,这使我开始思考。

假设您有一个类,并且该类具有要测试的方法。 但是您可以一次测试一个方法吗? 我想不是。 为了测试该方法,您需要调用一个或多个其他方法。 例如:

class MyClass { 
    int x;
    void foo() { x = 4; }
    boolean bar() { x = 3; }
    boolean check() { return x == 4; }
}

为了测试foo和bar,我需要使用check(),另一方面,为了测试检查,我需要使用foo()或bar()。

说,我必须遵循以下测试案例:

class MyClassTest {
    @Test
    void testFoo() {
        MyClass obj = new MyClass();
        obj.foo();
        assert obj.check();
    }
}

现在假设我们的同事更改了check()方法:

boolean check() { return x == 5; }

当然,testFoo()将失败,并且可能会认为foo方法存在问题。

因此,这看起来像是鸡鸡蛋的情况。 人们通常如何解决这个问题?

在这里单独测试方法可能没有多大意义,因为类的状态可以根据所调用方法的顺序进行更改。 在这种情况下,我将确保行为-或状态转换-能够按预期工作。 请参考以下三个测试,它们正确指定了类的行为:

class WhenFooWasCalled {
    @Test
    public void ThenCheckShouldReturnTrue {
        MyClass sut = new MyClass();
        sut.foo();
        assertTrue(sut.check());
    }
}

class WhenBarWasCalled {
    @Test
    public void ThenCheckShouldReturnFalse {
        MyClass sut = new MyClass();
        sut.bar();
        assertFalse(sut.check());
    }
}

class WhenNothingWasCalled {
    @Test
    public void ThenCheckShouldReturnFalse {
        MyClass sut = new MyClass();
        assertFalse(sut.check());
    }
}

更新:我添加了第三个测试用例:如果没有调用foo()和bar(),check()的行为如何。

您不会为单个方法编写测试,而是为单个需求编写测试。 在这种情况下,您的课程似乎有两个要求:

  1. “最后一次调用foo时, check必须返回true
  2. “最后一次调用bar时, check必须返回false

因此,您将编写两个单元测试,每个单元测试一个,以验证该类是否正确地实现了它(您可能想提出第三个要求:什么都没有调用时应该执行的check )。 当您的同事进行上述更改时,他没有破坏foo方法,也没有破坏check方法。 他所打破的是第一个要求。 现在,他必须以某种方式更改班级,以使其再次满足。 他如何完成此操作(更改foo和/或更改check )并不重要。

这对于具有内部可变状态的类很常见。 我认为您的问题将简化为在给定状态操作序列之后的单元测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM