使用Moq测试接受非原始参数的方法

时间:2010-02-11 15:59:58

标签: asp.net-mvc moq

我正在尝试为ASP.Net MVC控制器操作编写测试。

我想测试一下该动作是否在一个注入的服务上调用一个特定的方法,所以我在嘲笑该服务并使用.Verify。

因此,在简单的情况下,我的控制器中有以下操作:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(string title)
    {
        _cmsService.AddPage(title);

        return View("Edit");
    }

使用服务界面...

public interface ICmsService
{
    void AddPage(string request);
}

以及以下测试...

        //Arrange
        const string pageTitle = "Test Page";

        var cmsService = new Mock<ICmsService>();

        cmsService.Setup(service => service.AddPage(pageTitle));

        var controller = new PageController(cmsService.Object);

        //Act
        var result = controller.Create(pageTitle) as ViewResult;

        //Assert
        cmsService.Verify(service => service.AddPage(pageTitle), Times.Once());

现在我想重构我的服务操作以使用请求和响应对象......

public interface ICmsService
{
    CmsServiceAddPageResponse AddPage(CmsServiceAddPageRequest request);
}

所以我相应地改变了我的行动......

    public ActionResult Create(string title)
    {
        var request = new CmsServiceAddPageRequest()
                          {
                              PageName = title
                          };

        var response = _cmsService.AddPage(request);

        return View("Edit");
    }

还有我的测试...

        //Arrange
        const string pageTitle = "Test Page";

        var cmsService = new Mock<ICmsService>();

        var request = new CmsServiceAddPageRequest() {PageName = pageTitle};

        cmsService.Setup(service => service.AddPage(request));

        var controller = new PageController(cmsService.Object);

        //Act
        var result = controller.Create(pageTitle) as ViewResult;

        //Assert
        cmsService.Verify(service => service.AddPage(request), Times.Once());

但是现在当我运行测试时,我得到以下消息......

TestCase 'Web.Test.PageControllerTest.CreateNewPagePost'
failed: Moq.MockException : 
Invocation was performed more than once on the mock: service => service.AddPage(value(Web.Test.PageControllerTest+<>c__DisplayClass1).request)
    at Moq.Mock.ThrowVerifyException(IProxyCall expected, Expression expression, Times times)
    at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times)
    at Moq.Mock.Verify[T,TResult](Mock mock, Expression`1 expression, Times times, String failMessage)
    at Moq.Mock`1.Verify[TResult](Expression`1 expression, Times times)
    PageControllerTest.cs(67,0): at Web.Test.PageControllerTest.CreateNewPagePost()

我应该怎么做才能测试接受非基本类型的方法?

由于

2 个答案:

答案 0 :(得分:3)

我认为第一个答案的更好的替代方法是实现自定义匹配器而不是更改代码以匹配您的测试框架。从:http://code.google.com/p/moq/wiki/QuickStart

// custom matchers
mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>();
...
public string IsLarge() 
{ 
  return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100);
}

答案 1 :(得分:1)

如果在CmsServiceAddPageRequest对象中重写Equals,它应该正确地比较它们。