3

我在我的 MVC 3 项目中使用 Ninject 并且效果很好,但我想知道在我的测试项目中使用 Ninject 的好方法是什么?

以下是我目前做事的方式:

[Fact]
public void ReturnsViewResultWithDefaultViewName()
{
    // Arrange
    var membershipService = new MembershipService(new EFMembershipProvider());
    var transactionService = new TransactionService();
    var controller = new HomeController(membershipService, transactionService);

    // Act
    var result = controller.Index();

    // Assert
    var viewResult = Assert.IsType<ViewResult>(result);
    Assert.Empty(viewResult.ViewName);
}
4

2 回答 2

4

普遍接受的建议是:不要在测试中使用 Ninject - 使用 IoC 的目标是您首先不需要在测试中使用繁重的东西。当事情变得太复杂时,它会帮助代码告诉你。

如果您觉得您的代码确实具有无法通过改进设计来使您满意的复杂性,请查看AutoFixture,尤其是 xunit.net 集成 - 它和/或其他自动模拟容器可能是合适的,因为它们直接解决了您所关心的问题'在你的问题中很重要。

于 2011-02-20T16:18:43.460 回答
4

看来您的测试正在使用 NInject 在 MVC 框架下运行时将填写的所有依赖类。在单元测试中使用模拟时,IoC 的真正好处就出现了。

如果您使用 Moq,您的单元测试可能类似于:

    // Arrange
    var membershipService = new Mock<IMembershipService>();
    membershipService.Setup(m => m.CurrentUser)
        .Returns(new MyPrincipal() { Name = "Bob", ID = 12345 });
    var transactionService = new Mock<ITransactionService>();
    transactionService.Setup(t => t.SomeRandomMethod())
        .Throws<MyBadTransactionException>();
    var controller = new HomeController(membershipService.Object, transactionService.Object);
...

这使您能够创建在使用应用程序的正常“运行时”对象时可能很难导致的条件。此外,它将您的被测类(示例中的 HomeController)与其他对象完全隔离,这将使您的单元测试运行得更快。

有关更多信息,请参阅起量项目或谷歌“起订量”。当然,还有替代的模拟框架。我只是更熟悉起订量。

于 2011-03-09T18:41:44.360 回答