I am trying to auto mock ApiController class in my test cases. It worked perfectly when I was using WebApi1. I started to use WebApi2 on the new project and I am getting this exception thrown after I try to run my new tests:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Security.Cryptography.CryptographicException: pCertContext is an invalid handle.
at System.Security.Cryptography.CAPI.CertSetCertificateContextProperty(SafeCertContextHandle pCertContext, UInt32 dwPropId, UInt32 dwFlags, SafeLocalAllocHandle safeLocalAllocHandle)
at System.Security.Cryptography.X509Certificates.X509Certificate2.set_Archived(Boolean value)
My test code:
[Theory, AutoMoqData]
public void approparte_status_code_is_returned(
string privateKey,
UsersController sut)
{
var response = sut.GetUser(privateKey);
var result = response;
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
}
Test case does work if I create sut manually:
[Theory, AutoMoqData]
public void approparte_status_code_is_returned(
string privateKey,
[Frozen]Mock<IUserModel> stubModel)
{
var sut = new UsersController(stubModel.Object);
var response = sut.GetUser(privateKey);
var result = response;
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
}
It's seems that something goes wrong when trying to mock the ControllerContext.RequestContext.ClientCertificate I've tried to create a fixture without it (using AutoFixture .Without() method) but then even the old tests started to fail.
My AutoMoqDataAttribute:
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture()
.Customize(new WebApiCustomization()))
{
}
}
WebApi customization:
public class WebApiCustomization : CompositeCustomization
{
public WebApiCustomization()
: base(
new HttpRequestMessageCustomization(),
new AutoMoqCustomization())
{
}
}
HttpRequestMessage customization:
public class HttpRequestMessageCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customize<HttpRequestMessage>(c => c
.Without(x => x.Content)
.Do(x =>
{
x.Properties[HttpPropertyKeys.HttpConfigurationKey] = new HttpConfiguration();
})
);
}
}
UsersController:
/// <summary>
/// Handles user's account.
/// </summary>
[RoutePrefix("api/v1/users/{privateKey:length(64)}")]
public class UsersController : ApiController
{
private readonly IUserModel _model;
public UsersController(IUserModel model)
{
_model = model;
}
/// <summary>
/// Returns a user.
/// </summary>
/// <param name="privateKey">The private key of the user.</param>
/// <returns>
/// 200 (OK) with user data is returned when user is found.
/// 404 (Not found) is returned when user is not found.
/// </returns>
[HttpGet]
[Route("")]
public HttpResponseMessage GetUser(string privateKey)
{
UserProjection projection;
try
{
projection = new UserProjection(_model.Get(privateKey));
}
catch (UserNotFoundException)
{
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
return Request.CreateResponse(HttpStatusCode.OK, projection);
}
}