ApiControllers
are quite difficult to wire up, because you'll need to assign certain properties to them in order for everything to work. At the very least, you'll need the Request
property to be assigned, because otherwise, the Controller
can't invoke Request.CreateResponse
. Thus, switching off auto-properties for ApiController
instances isn't a good strategy. Instead, you can configure AutoFixture to wire up HttpRequestMessage
instances correctly.
Web API 1
With ASP.NET Web API 1, I usually use a Customization like this:
public class WebApiCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<HttpRequestMessage>(c => c
.Do(x =>
x.Properties.Add(
HttpPropertyKeys.HttpConfigurationKey,
new HttpConfiguration())));
}
}
Since auto-properties are on by default, this is going to assign an appropriate instance of HttpRequestMessage
to ApiController.Request
. Together with an Auto-mocking Customization, Fixture
can now create instances of all your ApiController
classes.
Web API 2
With ASP.NET Web API 2 (5.0.0.0), things are a little more complicated, but with a bit of trial and error, I got this Customization to pass 808 tests:
public class WebApiCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<HttpConfiguration>(c => c
.OmitAutoProperties());
fixture.Customize<HttpRequestMessage>(c => c
.Do(x =>
x.Properties.Add(
HttpPropertyKeys.HttpConfigurationKey,
fixture.Create<HttpConfiguration>())));
fixture.Customize<HttpRequestContext>(c => c
.Without(x => x.ClientCertificate));
}
}
Conventions
If you package that into an [AutoData]
attribute, you should be able to refactor your test to:
[Theory, BasicConventions]
public void GetVersionOnSiteVersionControllerReturnsASiteVersion(
SiteVersionController sut,
SiteVersion expected)
{
SiteVersion actual = null;
var response = sut
.GetSiteVersion()
.ExecuteAsync(new CancellationToken())
.Result
.TryGetContentValue<SiteVersion>(out actual);
actual.AsSource().OfLikeness<SiteVersion>().ShouldEqual(expected);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…