Использование Moq для тестирования методов, которые принимают непримитивные аргументы - PullRequest
1 голос
/ 11 февраля 2010

Я пытаюсь написать тест для действия контроллера 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()

Что мне делать, чтобы проверить метод, который принимает не примитивный тип?

Спасибо

Sandy

Ответы [ 2 ]

3 голосов
/ 11 февраля 2010

Я думаю, что лучшей альтернативой первому ответу будет реализация пользовательского сопоставления, а не изменение кода в соответствии с вашей средой тестирования. От: 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 голос
/ 11 февраля 2010

Если вы переопределяете Equals в объекте CmsServiceAddPageRequest, он должен сравнивать их правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...