【问题标题】:Unit testing with mvc api & ninject使用 mvc api 和 ninject 进行单元测试
【发布时间】:2013-10-21 09:21:35
【问题描述】:

对不起,如果这是一个愚蠢的问题,我只是不知道如何开始编写一些单元测试。

我有一个包含 api 和单元测试项目的解决方案。该 api 有一个存储库/接口,用于使用 ninject 访问数据。

我的问题是如何对我的 api 控制器进行单元测试。我已经阅读了一些关于 Moq 的信息,但不确定是否需要使用它,因为我想针对我的数据库进行测试。

我读到我需要使用[TestInitialize] 属性

[TestInitialize]
public void MyTestInitialize()
{
  var kernel = NinjectWebCommon.CreatePublicKernel();
  kernel.Bind<BusinessController>().ToSelf();
}

我的问题是我的测试项目无法解析 CreatePublicKernel 检查 api 中的 NinjectWebCommon 类,没有名为 CreatePublicKernel 的函数。

我在这里错过了什么?

【问题讨论】:

    标签: unit-testing asp.net-web-api ninject


    【解决方案1】:

    Ninject(或其他 DI 库)仅用于向控制器的构造函数提供依赖项。例如。如果你需要 BusinessController 需要两个存储库,那么控制器应该有构造函数来期望这些依赖关系:

    public BusinessController(IUserRepository userRepository, 
                              IOrderRepository orderRepository)
    {
        _userRepository = userRepository;
        _orderRepository = orderRepository;
    }
    

    如果您想为您的控制器编写单元测试,您应该提供这些存储库的模拟实现。使用Moq 或其他框架来创建模拟:

    var userRepositoryMock = new Mock<IUserRepository>();
    var orderRepositoryMock = new Mock<IOrderRepository>();
    // setup mocks here
    var controller = new BusinessController(userRepositoryMock.Object,
                                            orderRepositoryMock.Object);
    

    如果您正在为控制器编写集成测试,您应该提供这些存储库的真实实现,它们使用一些真实的数据库。

    var userRepository = new NHibernateUserRepository();
    var orderRepository = new NHibernateOrderRepository();
    // prepare some data in database here
    var controller = new BusinessController(userRepository, orderRepository);
    

    您可以将控制器实例化移动到在每次测试之前执行的某个方法中(SetUp 或 TestInitialize 方法),以消除测试中的代码重复。


    更新:您也可以使用 Ninject 进行集成测试。只需创建 Ninject 模块,您的实际应用程序和集成测试都将使用它:

    public class FooModule : NinjectModule
    {
        public override void Load()
        {
            Bind<IUserRepository>().To<NHibernateUserRepository>();
            Bind<IOrderRepository>().To<NHibernateOrderRepository>();
            Bind<BusinessController>().ToSelf();
        }
    }
    

    然后使用此模块在 NinjectWebCommon.CreateKernel 方法中创建内核并在您的测试中创建内核:

    var kernel = new StandardKernel(new FooModule());
    var controller = kernel.Get<ValuesController>();
    

    【讨论】:

    • 感谢您的真正有用的回答。这让事情变得更加清晰了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 2017-04-12
    相关资源
    最近更新 更多