如何将测试单元代码分解为'Re-usable'代码?



我在某些测试方法中嘲笑HTTPContext。 我需要编写很多方法,所以我宁愿重用代码,也不愿每次都编写代码。 保持干燥。

我正在实现这种伪造(模拟)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());
}

这取决于您的需求。
也许创建一个类就足够了,该类将创建虚假的上下文实例。也许使用一些方法可以创建填充不同数据的上下文。

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();
    ...
}

相关内容

最新更新