Unit testing 使用mvc api进行单元测试;尼尼特

Unit testing 使用mvc api进行单元测试;尼尼特,unit-testing,asp.net-web-api,ninject,Unit Testing,Asp.net Web Api,Ninject,抱歉,如果这是一个愚蠢的问题,我只是不知道如何开始编写一些单元测试 我有一个包含api和单元测试项目的解决方案。api有一个用于使用ninject访问数据的存储库/接口 我的问题是如何最好地对api控制器进行单元测试。我读了一些关于Moq的书,但不确定是否需要使用它,因为我想对我的数据库进行测试 var userRepository = new NHibernateUserRepository(); var orderRepository = new NHibernateOrderReposit

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

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

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

var userRepository = new NHibernateUserRepository();
var orderRepository = new NHibernateOrderRepository();
// prepare some data in database here
var controller = new BusinessController(userRepository, orderRepository);
我已经读到我需要使用
[TestInitialize]
属性

[TestInitialize]
public void MyTestInitialize()
{
  var kernel = NinjectWebCommon.CreatePublicKernel();
  kernel.Bind<BusinessController>().ToSelf();
}
[测试初始化]
公共无效MyTestInitialize()
{
var kernel=NinjectWebCommon.CreatePublicKernel();
kernel.Bind().ToSelf();
}
我的问题是我的测试项目无法解决CreatePublicKernel 检查api中的NinjectWebCommon类时,没有名为CreatePublicKernel的函数

这里我缺少什么?

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

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);
您可以将控制器实例化移动到某个方法中,该方法在每次测试之前执行(SetUp或TestInitialize方法),以便从测试中删除代码重复


更新:您还可以使用Ninject进行集成测试。只需创建Ninject模块,即可供实际应用程序和集成测试使用:

public class FooModule : NinjectModule
{
    public override void Load()
    {
        Bind<IUserRepository>().To<NHibernateUserRepository>();
        Bind<IOrderRepository>().To<NHibernateOrderRepository>();
        Bind<BusinessController>().ToSelf();
    }
}
公共类FooModule:ninject模块
{
公共覆盖无效负载()
{
绑定()到();
绑定()到();
Bind().ToSelf();
}
}
然后使用此模块在NinjectWebCommon.CreateKernel方法中创建内核,并在测试中创建内核:

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

感谢您提供了非常有用的答案。这让事情变得更清楚了