无法使用Moq模拟Configuration.Formatters

时间:2018-03-18 17:02:07

标签: unit-testing asp.net-web-api mocking moq mediatypeformatter

我正在开发一个ASP.NET Web API应用程序。我对我的应用程序中的每个组件进行单元测试。我正在使用Moq Unit Test框架来模拟数据。现在我试图在我的单元测试中模拟Configuration.Formatters.JsonFormatter,因为我在单元测试下的操作是使用它如下。

public HttpResponseMessage Register(model)
{
    return new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.BadRequest,
                Content = new ObjectContent<List<string>>(errors, Configuration.Formatters.JsonFormatter)
            };
}

我试图在单元测试中模拟Configuration.Formatters.JsonFormatter,如下所示。

[TestMethod]
public void Register_ReturnErrorsWithBadRequest_IfValidationFails()
{
    PostUserRegistration model = new PostUserRegistration {
        Name = "Wai Yan Hein",
        Email = "waiyanhein@gmail.com",
        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);
}

当我运行我的单元测试时,它给了我这个错误。 enter image description here

  

System.NotSupportedException:非虚拟设置无效   (在VB中可覆盖)成员:x =&gt; x.JsonFormatter

那么,我该如何解决这个错误呢?我该如何模仿Configuration.Formatters.JsonFormatter呢?

1 个答案:

答案 0 :(得分:1)

您不应该测试框架是否正在执行它的设计目标。相反,类似于之前在评论中建议的内容,我建议使用ApiController的内置方法,并将操作重构为该版本的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();
}

上述方法的单元测试的简单示例可能看起来像这样......

[TestMethod]
public void Register_ReturnErrorsWithBadRequest_IfValidationFails() {            
    //Arrange
    PostUserRegistration model = new PostUserRegistration {
        Name = "Wai Yan Hein",
        Email = "waiyanhein@gmail.com",
        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);
}

如果在测试方法中不会引用/调用注入的依赖项,您也可以放弃模拟并注入null。然而,这取决于原始问题中未提供的代码。