我在一些测试方法中嘲笑HTTPContext。我有很多需要编写的方法,所以我宁愿重复使用代码而不是每次都写代码。保持干燥。
我正在实施this method of Faking (Mocking) HTTPContext。我读到我需要将其分解为工厂,以便在其他单元测试中重复使用它。
问题:如何将此代码放入工厂以在单元测试中重复使用?还有一种更好的方法吗?工厂'重用这个?我该如何实现呢。
测试代码
public class MyController : Controller
{
[HttpPost]
public void Index()
{
Response.Write("This is fiddly");
Response.Flush();
}
}
//Unit Test
[Fact]
public void Should_contain_fiddly_in_response()
{
var sb = new StringBuilder();
var formCollection = new NameValueCollection();
formCollection.Add("MyPostedData", "Boo");
var request = A.Fake<HttpRequestBase>();
A.CallTo(() => request.HttpMethod).Returns("POST");
A.CallTo(() => request.Headers).Returns(new NameValueCollection());
A.CallTo(() => request.Form).Returns(formCollection);
A.CallTo(() => request.QueryString).Returns(new NameValueCollection());
var response = A.Fake<HttpResponseBase>();
A.CallTo(() => response.Write(A<string>.Ignored)).Invokes((string x) => sb.Append(x));
var mockHttpContext = A.Fake<HttpContextBase>();
A.CallTo(() => mockHttpContext.Request).Returns(request);
A.CallTo(() => mockHttpContext.Response).Returns(response);
var controllerContext = new ControllerContext(mockHttpContext, new RouteData(), A.Fake<ControllerBase>());
var myController = GetController();
myController.ControllerContext = controllerContext;
myController.Index();
Assert.Contains("fiddly", sb.ToString());
}
答案 0 :(得分:1)
这取决于您的需求 也许它足以创建一个可以创建伪上下文实例的类。也许有一些方法可以让你创建充满不同数据的上下文。
public class FakeContextFactory
{
public ControllerContext Create() {/*your mocking code*/}
public ControllerContext Create(NameValueCollection formVariables) {...}
...
}
public void Test()
{
var context = new FakeContextFactory().Create();
...
}
在某些情况下,它可能是一个静态工厂,由具有静态方法的类表示。
如果您需要很多不同的上下文,那么使用构建器模式可能会更好。
public void Test()
{
var context = FakeContextBuilder.New()
.SetRequestMethod("POST")
.Build();
...
}