I am developing an ASP.NET web API application. I am unit testing to every component in my application. I am using Moq Unit Test framework to mock the data. Now I am trying to mock the Configuration.Formatters.JsonFormatter
in my Unit test because my action under unit test is using it as follows:
public HttpResponseMessage Register(model)
{
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.BadRequest,
Content = new ObjectContent<List<string>>(errors, Configuration.Formatters.JsonFormatter)
};
}
I am trying to mock the Configuration.Formatters.JsonFormatter
in the Unit Test as follow.
[TestMethod]
public void Register_ReturnErrorsWithBadRequest_IfValidationFails()
{
PostUserRegistration model = new PostUserRegistration {
Name = "Wai Yan Hein",
Email = "[email protected]",
Password = ""
};
Mock<JsonMediaTypeFormatter> formatterMock = new Mock<JsonMediaTypeFormatter>();
Mock<MediaTypeFormatterCollection> formatterCollection = new Mock<MediaTypeFormatterCollection>();
formatterCollection.Setup(x => x.JsonFormatter).Returns(formatterMock.Object);
Mock<HttpConfiguration> httpConfigMock = new Mock<HttpConfiguration>();
httpConfigMock.Setup(x => x.Formatters).Returns(formatterCollection.Object);
Mock<IAccountRepo> accRepoMock = new Mock<IAccountRepo>();
AccountsController controller = new AccountsController(accRepoMock.Object);
controller.Configuration = httpConfigMock.Object;
controller.ModelState.AddModelError("", "Faking some model error");
HttpResponseMessage response = controller.Register(model);
Assert.AreEqual(response.StatusCode, System.Net.HttpStatusCode.BadRequest);
}
When I run my unit tests, it is giving me this error.
System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: x => x.JsonFormatter
So, how can I fix that error and how can I mock Configuration.Formatters.JsonFormatter
?
You should not have to test that the framework is doing what it was designed to do. Instead, similar to what was suggested before in comments, I suggest using the built in methods of the ApiController
and also refactoring the action to the syntax suggested from documentation for that version of Asp.Net Web API
public IHttpActionResult Register(PostUserRegistration model) {
if (!ModelState.IsValid)
return BadRequest(ModelState); //<-- will extract errors from model state
//...code removed for brevity
return Ok();
}
A simple example of a unit test for the above method could look something like this...
[TestMethod]
public void Register_ReturnErrorsWithBadRequest_IfValidationFails() {
//Arrange
PostUserRegistration model = new PostUserRegistration {
Name = "Wai Yan Hein",
Email = "[email protected]",
Password = ""
};
var accRepoMock = new Mock<IAccountRepo>();
var controller = new AccountsController(accRepoMock.Object);
controller.ModelState.AddModelError("", "Faking some model error");
//Act
var response = controller.Register(model) as InvalidModelStateResult; //<-- Note the cast here
//Assert
Assert.IsNotNull(response);
}
If the injected dependency is not going to be referenced/invoked in the method under test you could also forego the mock and inject null
. That however is dependent on code not provided in the original question.