I am using AutoFixture to try to test my controllers for a WebApi site. I am using the AutoData feature with Moq as noted on Ploeh’s blog.
My controller takes an IDepartmentManager in the constructor. Here is my test:
[Theory, AutoMoqData]
public void GetCallsManagerCorrectly(
[Frozen]Mock<IDepartmentManager> departmentManagerMock,
DepartmentsController sut)
{
// Fixture setup
// Exercise system
sut.Get();
// Verify outcome
departmentManagerMock.Verify(d => d.GetAllDepartments(), Times.Exactly(1));
// Teardown
}
When I run this test it fails with the following:
GetCallsManagerCorrectly has failed:
System.InvalidOperationException : An exception was thrown while
getting data for theory
Provision.Tests.WebApiControllerTests.DepartmentControllerTests.GetCallsManagerCorrectly:
System.Reflection.TargetInvocationException: Exception has been thrown
by the target of an invocation. —> System.ArgumentException: Only
‘http’ and ‘https’ schemes are allowed. Parameter name: value at
System.Net.Http.HttpRequestMessage.set_RequestUri(Uri value)
First of all, is this still a valid and recommended way to write these tests? I love how small it makes everything.
Secondly, what should I do to fix this? If I change my test to this:
[Theory, AutoMoqData]
public void GetCallsManagerCorrectly(
[Frozen]Mock<IDepartmentManager> departmentManagerMock)
{
// Fixture setup
DepartmentsController sut =
new DepartmentsController(departmentManagerMock.Object);
// Exercise system
sut.Get();
// Verify outcome
departmentManagerMock.Verify(d => d.GetAllDepartments(), Times.Exactly(1));
// Teardown
}
it passes, but then I lose the ability to have the controller built up automatically and still be ok if I add parameters to the constructor.
This is definitely the recommended way to write tests with AutoFixture. The issue is pretty easy to fix.
Instead of implementing the [AutoMoqData] attribute as described in the blog post, I’d recommend creating a slightly different attribute and Customization – a set that basically will act as a set of conventions for an entire unit test project. I always do this, and I always go to great lengths to have only a single set of conventions for a single unit test project. A single set of conventions help me keep my tests (and the SUTs) consistent.
The MyWebApiCustomization could be defined like this:
Note the additional HttpSchemeCustomization class – that should do the trick.
Please note that the order of Customizations matters.