使用Ninject时如何基于接口模拟Context?
How to mock the Context based on an interface when using Ninject?
我有正常的 Entity Framework 上下文,是这样的:
public class LikvidoWebsitesApiContext : IdentityDbContext<ApplicationUser>, ILikvidoWebsitesApiContext
{
// code
}
我做了一个界面,里面有我的DBSets
。
在我的正常解决方案中,我在 Ninject 中设置如下:
kernel.Bind<ILikvidoWebsitesApiContext>().To<LikvidoWebsitesApiContext>().InRequestScope();
我通过在构造函数中添加 ILikvidoWebsitesApiContext
在我的服务中使用上下文,然后我可以使用数据库。
我的问题是:如何在单元测试中设置它?
我已尝试执行以下操作:
kernel.Bind(typeof(ILikvidoWebsitesApiContext))
.To(typeof(Mock<LikvidoWebsitesApiContext>))
.Register(true);
(使用Moq
框架)
然而,这给出了:
System.InvalidCastException: 'Unable to cast object of type 'Moq.Mock`1[Likvido.Domain.Services.Data.LikvidoWebsitesApiContext]' to type 'Likvido.Domain.Services.Data.ILikvidoWebsitesApiContext'.'
哪个确实有意义,但我不确定如何解决它?
快速浏览 Ninject wiki 后,我发现了
Providers, Factory Methods and the Activation Context
他们展示了如何使用 Provider
构建实例。
根据 wiki 中的建议,建议扩展 Provider<T>
,其中包括强类型。
public MoqContextProvider : Provider<ILikvidoWebsitesApiContext> {
protected override ILikvidoWebsitesApiContext CreateInstance(IContext context) {
var mock = new Mock<ILikvidoWebsitesApiContext>();
// Set up of mock members
return mock.Object;
}
}
然后只需插入容器即可
kernel.Bind<ILikvidoWebsitesApiContext>().ToProvider(new MoqContextProvider());
还有关于使用 工厂方法
的建议
A lighter weight alternative to writing IProvider
implementations is to bind a service to a delegate method.
kernal.Bind<ILikvidoWebsitesApiContext>()
.ToMethod(context => {
var mock = new Mock<ILikvidoWebsitesApiContext>();
// Set up of mock members
return mock.Object;
});
所提供的 Func
将绑定到延迟绑定的服务类型,并在需要新的服务实例(即 ILikvidoWebsitesApiContext
)时调用。
请记住,在使用 Moq 时,您需要设置所需的模拟行为。
我有正常的 Entity Framework 上下文,是这样的:
public class LikvidoWebsitesApiContext : IdentityDbContext<ApplicationUser>, ILikvidoWebsitesApiContext
{
// code
}
我做了一个界面,里面有我的DBSets
。
在我的正常解决方案中,我在 Ninject 中设置如下:
kernel.Bind<ILikvidoWebsitesApiContext>().To<LikvidoWebsitesApiContext>().InRequestScope();
我通过在构造函数中添加 ILikvidoWebsitesApiContext
在我的服务中使用上下文,然后我可以使用数据库。
我的问题是:如何在单元测试中设置它?
我已尝试执行以下操作:
kernel.Bind(typeof(ILikvidoWebsitesApiContext))
.To(typeof(Mock<LikvidoWebsitesApiContext>))
.Register(true);
(使用Moq
框架)
然而,这给出了:
System.InvalidCastException: 'Unable to cast object of type 'Moq.Mock`1[Likvido.Domain.Services.Data.LikvidoWebsitesApiContext]' to type 'Likvido.Domain.Services.Data.ILikvidoWebsitesApiContext'.'
哪个确实有意义,但我不确定如何解决它?
快速浏览 Ninject wiki 后,我发现了
Providers, Factory Methods and the Activation Context
他们展示了如何使用 Provider
构建实例。
根据 wiki 中的建议,建议扩展 Provider<T>
,其中包括强类型。
public MoqContextProvider : Provider<ILikvidoWebsitesApiContext> {
protected override ILikvidoWebsitesApiContext CreateInstance(IContext context) {
var mock = new Mock<ILikvidoWebsitesApiContext>();
// Set up of mock members
return mock.Object;
}
}
然后只需插入容器即可
kernel.Bind<ILikvidoWebsitesApiContext>().ToProvider(new MoqContextProvider());
还有关于使用 工厂方法
的建议A lighter weight alternative to writing
IProvider
implementations is to bind a service to a delegate method.
kernal.Bind<ILikvidoWebsitesApiContext>()
.ToMethod(context => {
var mock = new Mock<ILikvidoWebsitesApiContext>();
// Set up of mock members
return mock.Object;
});
所提供的 Func
将绑定到延迟绑定的服务类型,并在需要新的服务实例(即 ILikvidoWebsitesApiContext
)时调用。
请记住,在使用 Moq 时,您需要设置所需的模拟行为。