Mocking HttpResponse.StatusCode with AutoFixture and Moq
本文关键字:and Moq AutoFixture with HttpResponse StatusCode Mocking | 更新日期: 2023-09-27 18:32:23
我正在使用AutoFixture作为自动模拟容器,并希望模拟HttpResponse
,以便我可以验证是否已设置特定的StatusCode
。但是,当我打电话给SetupSet
时,我得到了一个NotImplementedException
:
var response = _fixture.Freeze<Mock<HttpResponseBase>>();
response
.SetupSet(x => x.StatusCode = It.IsAny<int>());
如果我只是使用一个新的 Mock of HttpResponseBase
,我不会有任何例外,但是我将不得不编写一个FreezeMoq
扩展方法,如 Mark Seemann 的 Frozen Mocks 博客文章中所解释的那样。
AutoFixture 在做什么,这意味着我无法在基类抛出NotImplementedException
的虚拟属性上设置一个集合,但是在仅使用 Moq 时可以设置?
Moq 的行为方式,您可以在没有 AutoFixture 的情况下重现该行为:
[Fact]
public void ReducedRepro()
{
var response = new Mock<HttpResponseBase>();
response.CallBase = true;
Assert.Throws<NotImplementedException>(() =>
response.SetupSet(x => x.StatusCode = It.IsAny<int>()));
}
上面的测试通过,证明当您将 Moq 设置为 CallBase
时,在这种情况下会抛出NotImplementedException
true
,这正是 AutoMoq 所做的。
在大多数情况下,将 CallBase
设置为 true 是模拟基类的适当配置(它对接口没有影响),因为这意味着您可以相信模拟类仍然具有所有默认行为,除非您重写虚拟方法。这样做的好处是,您不必为所有虚拟方法调用Setup
方法,否则会导致测试变脆。
但是,在这种情况下,它会导致失败,因为HttpResponseBase.StatusCode
是一个虚拟方法,通过从getter和setter中抛出NotImplementedException
来实现。这个设计决策是如何通过代码审查的,这超出了我的想象。
您可以使用SetupProperty
相当轻松地解决它:
[Fact]
public void Workaround()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var response = fixture.Freeze<Mock<HttpResponseBase>>();
response.SetupProperty(x => x.StatusCode);
response.Object.StatusCode = 42;
Assert.Equal(42, response.Object.StatusCode);
}
此测试通过,表明您现在可以分配和读取 StatusCode
属性的值。