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



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

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

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

我已经阅读我需要使用 [TestInitialize] 属性

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

问题是我的测试项目无法解析创建公共内核检查 API 中的 NinjectWebCommon 类,没有一个名为 CreatePublicKernel 的函数。

我在这里错过了什么?

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>();

最新更新