我正在关注TDD并遇到一个问题,如果我让一个测试成功,另外两个因为抛出异常而失败。好吧,我想抛出异常,但我也想验证其他行为。例如:
public class MyTests {
[Fact]
public void DoSomethingIsCalledOnceWhenCheckerIsTrue()
{
var checker = new Mock<IChecker>();
var doer = new Mock<IDoer>();
checker.Setup(x => x.PassesCheck).Returns(true);
var sut = new ThingThatChecksAndDoes(checker.Object,doer.Object);
sut.CheckAndDo();
checker.VerifyGet(x => x.PassesCheck, Times.Once());
doer.Verify(x => x.Do(),Times.Once());
}
[Fact]
public void DoSomethingIsNeverCalledWhenCheckerIsFalse()
{
var checker = new Mock<IChecker>();
var doer = new Mock<IDoer>();
checker.Setup(x => x.PassesCheck).Returns(false);
var sut = new ThingThatChecksAndDoes(checker.Object,doer.Object);
sut.CheckAndDo();
doer.Verify(x => x.Do(),Times.Never());
}
[Fact]
public void ThrowCheckDidNotPassExceptionWhenCheckDoesNotPass()
{
var checker = new Mock<IChecker>();
var doer = new Mock<IDoer>();
checker.Setup(x => x.PassesCheck).Returns(false);
var sut = new ThingThatChecksAndDoes(checker.Object,doer.Object);
Assert.Throws<CheckDidNotPassException>(() => { sut.CheckAndDo(); });
}
}
我接近这个有什么选择?什么,如果有的话,将是“首选”的选择?
答案 0 :(得分:1)
您的第一次和第二次测试通过。然后当你添加第三个测试时,其余的测试都会失败!。
使用TDD
“避免更改传递的现有测试。而是添加新测试。 仅在用户要求更改时才更改现有测试。“
我还假设你的SUT(被测系统)如下
public void CheckAndDo() {
var b = _checker.PassesCheck;
if (b) {
_doer.Do();
}
throw new CheckDidNotPassException();
}
在您的SUT中,当您抛出一个新的异常时,显然它会影响您执行执行逻辑的其余行为。
所以这里的选项是改变现有的测试。
给它一个命名良好的测试方法,并断言异常和验证。
[Test]
public void CheckAndDo_WhenPassesCheckTrue_DoCalledOnlyOnceAndThrowsCheckDidNotPassException()
{
var checker = new Mock<IChecker>();
var doer = new Mock<IDoer>();
checker.Setup(x => x.PassesCheck).Returns(true);
var sut = new ThingThatChecksAndDoes(checker.Object, doer.Object);
Assert.Throws<CheckDidNotPassException>(() => { sut.CheckAndDo(); });
doer.Verify(x => x.Do(), Times.Once());
}
您需要考虑的其他事项很少:
一个。 TDD产生良好的单元测试。良好的手段,可读,可维护和值得信赖的单元测试。 您的测试方法名称和对SUT的调用命名不佳。我想这只是针对demo / Stackoverflow问题。但我建议将来你提供一个真实世界的例子,除了“Do”“Something”之外的真实姓名 从TDD的角度来看,模糊名称并没有帮助,因为您根据需求设计了小型系统。
湾发布正确的代码。 在第一次测试中,你传递了模拟类型
var checker = new Mock<IChecker>();
var doer = new Mock<IDoer>();
var sut = new ThingThatChecksAndDoes(checker, doer);
你应该传递实例,即(checker.Object)
答案 1 :(得分:0)
当我测试类似的方法时