2012-05-16 21 views
0

我有這樣的控制器:Asp.net MVC測試與NUnit的創建操作方法,並Nsubstitute始終未能

[HttpPost] 
     public ActionResult Create(Company company) 
     { 

      // try to save the record 
      if (ModelState.IsValid) 
      { 

       // create the command 
       var command = new CreateOrUpdateCompanyCommand 
       { 
        CompanyId = company.CompanyId, 
        Code = company.Code, 
        Name = company.Name 
       }; 

       // check for errors 
       IEnumerable<ValidationResult> errors = _commandBus.Validate(command); 

       ModelState.AddModelErrors(errors); 

       if (ModelState.IsValid) 
       { 
        var result = _commandBus.Submit(command); 
        if (result.Success) 
         return RedirectToAction("Index"); 
       } 

      } 

      // if fail 
      return View("Create", company); 

     } 

我有這個測試NUnit的:

[Test] 
     public void Create() 
     { 

      const string expectedRouteName = "Index"; 

      // Mock the arguments 
      var mockRepository = Substitute.For<ICompanyRepository>(); 
      var mockProcessor = Substitute.For<ICommandBus>(); 

      // Arrange 
      var controller = new CompanyController(mockProcessor, mockRepository); 

      // Act 
      var company = new Company 
      { 
       Code = "XXXXXXX", 
       CompanyId = 1, 
       Name = "Sample company" 
      }; 

      var result = controller.Create(company) as RedirectToRouteResult; 

      // Assert 
      Assert.IsNotNull(result, "Should return a ViewResult"); 
      Assert.AreEqual(expectedRouteName, result.RouteValues["action"], 
       "View name should have been '{0}'", expectedRouteName); 

     } 

這是型號:

公共類公司 {

[Key] 
public int CompanyId { get; set; } 

[Required(ErrorMessage = "* (xxxx)")] 
[MaxLength(7)] 
[RegularExpression("^([A-Z0-9]{7})$", ErrorMessage = "xxx")] 
[Display(Name = "Code")] 
public string Code { get; set; } 

[Required(ErrorMessage = "*")] 
[MaxLength(40)] 
[Display(Name = "Name")] 
public string Name { get; set; } 

}

當我運行測試時,此函數總是返回false:var result = _commandBus.Submit(command);並且測試失敗。

我不知道如何測試它?我應該嘲笑_commandBus並將其設置爲true?我以這種方式,但不成功的嘗試:

 var mockCommand = Substitute.For<ICommand>(); 

     mockProcessor.Submit(mockCommand).Success.Returns(true); 

要創建這個項目從這個http://efmvc.codeplex.com/

任何建議給我,我已經得到的靈感?謝謝。

+0

在我看來,你不應該在你的模擬設置示例代碼中創建一個模擬的命令。而只是嘲笑巴士。 –

+0

我試過了,但沒有奏效,所以我刪除了它... –

回答

2

您傳遞給mockProcessor.Submit(mockCommand).Success.Returns(true)的命令需要與被測代碼通過的命令相同。由於該方法消息自己的命令,這將永遠不會是這樣。

最簡單的解決方法是,當你設置你的替補匹配任何命令:

var result = CreateSuccessfulResult(); // <-- fill this in as appropriate 
mockProcessor.Submit(null).ReturnsForAnyArgs(result); 

設置在結果Success場直列按你原來的測試應太,我認爲,但我覺得它更清楚一點指定所需的結果。

你可以通過匹配預期的命令類型這改善了一下:

mockProcessor.Submit(Arg.Any<CreateOrUpdateCompanyCommand>()).Returns(result); 

您還可以檢查命令,如果你想測試通過:

mockProcessor 
    .Submit(Arg.Is<CreateOrUpdateCompanyCommand>(x => x.CompanyId = ...)) 
    .Returns(result); 

類似的方法可用於檢查Validate呼叫。

還有一點在NSubstitute docs信息。