这是我的一个单元测试类的示例(简化为基础)。在控制器中,当调用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...
}
答案 0 :(得分:1)
您能否显示正在测试的控制器代码?它可能与您如何设置模拟上下文有关,但如果没有看到控制器代码则很难分辨。
另外,如果在创建模拟时添加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.")
}
}