【发布时间】:2015-11-18 18:15:13
【问题描述】:
我正在尝试使用 TDD 方法实现一个 webserviceclass,它发出一堆 web 请求并解释响应。我将 webrequests 封装在几个接口中,以便我可以轻松地模拟它们。当通过 webserviceclass 请求某些东西时,实现的方法总是返回一个包含错误对象的特定响应对象。借助此错误对象,用户可以确定请求是否成功,以及具体的错误是什么。
在写了一堆测试之后,我意识到我在 Arrange 阶段重复了很多次:
var mock = new Mock<ISomeWebservices>();
var sut = new MyWebServiceClass(mock.Object);
mock.Setup(foo=>foo.SomeRequest(someData)).Returns(@"{""user"": ""12345"",""somedata"": ""60"",""someotherdata"":""2015-09-01T12:00:00.200Z""}");
sut.SomeRequest(someData,s=> response = s);
所有测试的前 2 行始终相同。总是有一个模拟的设置,它返回一些东西或抛出一个异常。根据我正在测试的请求,我当然必须设置不同的方法。 我尝试使用 Autofixture 来解决这个问题,这样我就可以为每个 webrequest 编写一个 ICustomization,但问题是我仍然需要访问模拟来进行测试特定设置。
另一个问题是断言阶段。因为我总是从请求中得到一个错误对象,所以我只在预期和错误时断言错误对象。
Assert.That(response.Error.Type,Is.EqualTo(ErrorInfo.ErrorType.IllegalToken));
Assert.That(response.Error.Message, Is.Not.Null);
Assert.That(response.Error.AdvisedAction, Is.Not.Null);
Assert.That(response.Error.RawData, Is.Not.Null);
因此,如果出现错误,则错误对象的某些属性应始终填写,而有些则可以。 (例如,如果错误是由异常触发的,则异常属性不应为 null 等) 据我了解,在一个单元测试中使用多个断言是一种不好的做法,因此我希望尽可能避免这种做法。
[编辑] 根据评论,拥有多个断言以及重复我提到的排列部分并不是那么糟糕。所以我不会为此使用 Autofixture。
【问题讨论】:
-
干性在编写单元测试时并不重要,因为它会导致脆弱的测试codebetter.com/karlseguin/2009/09/12/…
-
我不认为几个 Asserts 不好。测试不同的、不相关的东西是不好的。但是取回一个对象并测试属性是否正确对我来说是可以的。
-
对于你的sut,你不能有类变量,并使用Setup方法创建它吗?
标签: c# tdd nunit moq autofixture