使用mvc api和ninject进行单元测试

Div*_*Dan 7 unit-testing ninject asp.net-web-api

很抱歉,如果这是一个愚蠢的问题我不知道如何开始编写一些单元测试.

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

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

我已经读过我需要使用一个[TestInitialize]属性

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

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

我在这里错过了什么?

Ser*_*kiy 9

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

public BusinessController(IUserRepository userRepository, 
                          IOrderRepository orderRepository)
{
    _userRepository = userRepository;
    _orderRepository = orderRepository;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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


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

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

然后使用这个模块在你的测试中在NinjectWebCommon.CreateKernel方法和内核中创建内核:

var kernel = new StandardKernel(new FooModule());
var controller = kernel.Get<ValuesController>();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你真正有用的答案.这使事情现在变得更加清晰 (2认同)