[英]how to assert mock state simultaneous with thrown exception
我正在跟踪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(); });
}
}
我要解决这个问题有哪些选择? 如果有的话,什么是“首选”选择?
您的第一个和第二个测试通过。 然后,当您添加第三个测试时,其余测试将失败!
有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”以外的其他真实名称。“某些东西”从TDD的角度来看,具有歧义的名称无济于事,因为您是根据需求来设计小型系统的。
b。 发布正确的代码。 在您的第一个测试中,您通过了模拟类型
var checker = new Mock<IChecker>();
var doer = new Mock<IDoer>();
var sut = new ThingThatChecksAndDoes(checker, doer);
您应该传递实例,例如(checker.Object)
当我测试类似方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.