2013-02-04 47 views
1

下面是我的一個單元測試類(簡化爲基礎知識)的示例。在控制器中,當調用Index()操作方法時,對GetByID(1234)的調用總是會生成一個Ticket對象的新實例。該對象存在,但它的所有屬性都是null,即使我已將它們設置在我的假對象中。任何想法爲什麼?模擬知識庫返回具有空屬性的對象

我正在使用Moq。

單元測試

[TestClass] 
    public class TicketControllerTests : ControllerTestBase 
    { 
     protected Mock<ITicketRepository> MockTicketRepository = new Mock<ITicketRepository>(); 

     [TestMethod] 
     public void IndexActionModelIsTypeOfTicketModel() 
     { 
      //ARRANGE 
      Mock<HttpContextBase> context = FakeHttpContext(); 
      context.Setup(ctx => ctx.Session[SessionKeys.TokenData.ToString()]).Returns(Constants.TOKENDATA_SUBMITTER); 

      MockTicketRepository.Setup(x => x.GetById(It.IsAny<int>())).Returns(Constants.CLIENT_TICKET); 

      //ACT 
      var result = GetController(context.Object).Index(Constants.TICKET_ID); 
      var model = ((ViewResult)result).Model; 

      //ASSERT 
      Assert.IsInstanceOfType(model, typeof(TicketModel), "ViewModel should have been an instance of TicketModel."); 
     } 

     private TicketController GetController(HttpContextBase context) 
     { 
      var controller = new TicketController(MockTicketRepository.Object); 
      controller.ControllerContext = GetControllerContext(context, controller); 
      return controller; 
     } 
    } 

Constants.CLIENT_TICKET

public static Ticket CLIENT_TICKET 
     { 
      get 
      { 
       var ticket = new Ticket 
       { 
        CategoryID = 1, 
        CreatedByUserId = 4 
       }; 

       ticket.Clients.Add(new Client { ShortName = "Test Client 1"}); 
       ticket.Clients.Add(new Client { ShortName = "Test Client 2" }); 

       ticket.User = new User {FirstName = "First", LastName = "Last"}; 

       return ticket; 
      } 
     } 

控制器

private readonly ITicketRepository _ticketRepository; 

public TicketController(ITicketRepository ticketRepository) 
{ 
    _ticketRepository = ticketRepository; 
} 

public ActionResult Index(int id) 
{ 
    var ticket = _ticketRepository.GetById(id); 

    // etc... 
} 

回答

1

你能顯示的C測試中的ontroller代碼?這可能與您如何設置模擬的上下文有關,但很難說沒有看到控制器代碼。

此外,如果添加MockBehavior.Strict當您創建模擬,它會彈了出來,如果調用沒有相應的期望:

protected Mock<ITicketRepository> MockTicketRepository = new Mock<ITicketRepository>(MockBehavior.Strict); 

UPDATE 我試圖剝奪一切恢復使該測試儘可能簡單,以嘗試隔離問題。以下是我想到的:

[TestClass] 
public class TicketControllerTests : ControllerTestBase 
{ 
    protected Mock<ITicketRepository> MockTicketRepository; 

    [TestMethod] 
    public void IndexActionModelIsTypeOfTicketModel() 
    { 
     //ARRANGE 
     MockTicketRepository = new Mock<ITicketRepository>(MockBehavior.Strict); 
     MockTicketRepository.Setup(x => x.GetById(Constants.TICKET_ID)).Returns(Constants.CLIENT_TICKET); 
     var controller = new TicketController(MockTicketRepository.Object); 

     //ACT - try to keep ACT as lean as possible, ideally just the method call you're testing 
     var result = controller.Index(Constants.TICKET_ID); 

     //ASSERT 
     var model = ((ViewResult)result).ViewData.Model; 
     Assert.That(model, Is.InstanceOfType<TicketModel>(), "ViewModel should have been an instance of TicketModel.") 
    } 
} 
+0

我粘貼的一些代碼是隻是爲了讓它工作而玩弄的結果。但是,使用Constants.TICKET_ID不起作用。請參閱我幾分鐘前編寫的代碼編輯。即使在單元測試中調用Setup()之後,我也無法得到預期的對象,因此我認爲它與控制器無關。但是,第一行(在一些警戒條款之後)是var ticket = _ticketRepository.GetById(id); – Scott

+1

編輯中的代碼按預期工作(無雙關語意圖)。如果您在模擬上創建了一個設置,然後檢查對象屬性,那麼正在模擬的實際代碼沒有運行,所以模擬的實例不會包含任何內容。請記住,moq用於創建對真實對象的期望 - 它不會獨立運行 – levelnis

+0

啊,謝謝你。我仍然認爲它不是控制器,就像我說的那樣,沒有什麼奇特的事情發生,只是調用_ticketRepository.GetById(id),其中'id'來自路由值(並且是整數)。 – Scott