Repetitive code in unit-tests

autofixture, c#, moq, nunit, unit-testing

Solution

You can create a composite Customization that will customize the fixture by using all contained customizations.

public class HttpMocksCustomization : CompositeCustomization
{
    public HttpMocksCustomization()
        : base(
            new AutoMoqCustomization(),
            new HttpWebClientWrapperMockCustomization(),
            new HttpWebResponseWrapperMockCustomization()
            // ...
            )
    {
    }
}

Each customization can be defined as follow:

public class HttpWebClientWrapperMockCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        var mock = new Mock<IHttpWebClientWrapper>();
        mock.Setup(m => m.GetResponse()).Returns(httpResponseMock.Object);

        fixture.Inject(mock);
    }
}

public class HttpWebResponseWrapperMockCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        var mock = new Mock<IHttpWebResponseWrapper>();
        mock.Setup(m => m.StatusCode).Returns(HttpStatusCode.OK);

        fixture.Inject(mock);
    }
}

// The rest of the Customizations.

Then inside the test method you can do this:

var fixture = new Fixture().Customize(new HttpMocksCustomization());

That way, when you request a Mock instance you don't have to repeat the setup steps. The one we customized earlier will be returned:

var httpClientMock = fixture.Freeze<Mock<IHttpWebClientWrapper>>();

However, if you use xUnit.net, things can be simplified even further.

You can create an AutoDataAttribute-derived type to provide auto-generated data specimens generated by AutoFixture as an extention to xUnit.net's Theory attribute:

public class AutoHttpMocksDataAttribute : AutoDataAttribute
{
    public AutoHttpMocksDataAttribute()
        : base(new Fixture().Customize(new HttpMocksCustomization()))
    {
    }
}

Then, in your test method you can pass the Mocks as arguments:

[Theory, AutoHttpMocksData]
public void MyTestMethod([Freeze]Mock<IHttpWebClientWrapper> httpClientMock, [Freeze]Mock<IHttpWebResponseWrapper> httpResponseMock)
{
    // ...
} 

Problem

We find ourselves coding repetitive fixture/mock setups in many test-cases - like this case: ``` var fixture = new Fixture().Customize(new AutoMoqCustomization()); var encodingMock = fixture.Freeze<Mock<IEncodingWrapper>>(); var httpClientMock = fixture.Freeze<Mock<IHttpWebClientWrapper>>(); var httpResponseMock = fixture.Freeze<Mock<IHttpWebResponseWrapper>>(); var httpHeaderMock = fixture.Freeze<Mock<IHttpHeaderCollectionWrapper>>(); var etag = fixture.CreateAnonymous<string>(); byte[] data = fixture.CreateAnonymous<byte[]>(); Stream stream = new MemoryStream(data); encodingMock.Setup(m => m.GetBytes(It.IsAny<string>())).Returns(data); httpHeaderMock.SetupGet(m => m[It.IsAny<string>()]).Returns(etag).Verifiable(); httpClientMock.Setup(m => m.GetResponse()).Returns(httpResponseMock.Object); httpResponseMock.Setup(m => m.StatusCode).Returns(HttpStatusCode.OK); httpResponseMock.SetupGet(m => m.Headers).Returns(httpHeaderMock.Object); httpResponseMock.Setup(m => m.GetResponseStream()).Returns(stream); ``` As per the idea that the tests should be self-contained and readable from start to end we dont use magical Setup/Teardown methods. Can we in any way (AutoFixture customizations, helper methods) reduce the "grunt work" of these tests?

Original source