Dependency injection 将Ninject.MockingKernel与Asp.Net Web API一起使用
我已经使用Ninject建立了一个Web API项目,并使用了详细的修复程序使其与最新版本的Web API一起工作。一切正常,但我现在正试着写一些测试 我正在使用内存托管来运行测试项目,详细说明如下,因为我有一个执行身份验证的Dependency injection 将Ninject.MockingKernel与Asp.Net Web API一起使用,dependency-injection,ninject,ninject-extensions,Dependency Injection,Ninject,Ninject Extensions,我已经使用Ninject建立了一个Web API项目,并使用了详细的修复程序使其与最新版本的Web API一起工作。一切正常,但我现在正试着写一些测试 我正在使用内存托管来运行测试项目,详细说明如下,因为我有一个执行身份验证的DelegatingHandler,然后在所有Api控制器使用的请求消息上设置一个属性 因此,我为我的测试准备了一个基类,并且有一个SetUp方法,在这里我设置了HttpServer和配置,这基本上是从我的工作Ninject代码中获取的: [设置] 公共作废设置() { 引
DelegatingHandler
,然后在所有Api控制器使用的请求消息上设置一个属性
因此,我为我的测试准备了一个基类,并且有一个SetUp
方法,在这里我设置了HttpServer
和配置,这基本上是从我的工作Ninject代码中获取的:
[设置]
公共作废设置()
{
引导程序=新引导程序();
DynamicModuleUtility.RegisterModule(
类型(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(
类型(NinjectHttpModule));
初始化(CreateKernel);
var config=新的HttpConfiguration();
config.Routes.MapHttpRoute(“登录”,
“api/auth/token”,
新建{controller=“Users”,action=“Login”});
config.IncludeErrorDetailPolicy=
IncludeErrorDetailPolicy。始终;
config.DependencyResolver=
新的NinjectResolver(CreateKernel());
config.MessageHandlers.Add(
新的AuthenticationHandler(CreateUserManager());
服务器=新的HttpServer(配置);
}
这就是我如何创建MoqMockingKernel
:
private静态IKernel CreateKernel()
{
var kernel=new MoqMockingKernel();
kernel.Bind()
.ToMethod(ctx=>()=>newbootstrapper().Kernel);
kernel.Bind()
.To();
注册服务(内核);
GlobalConfiguration.Configuration.DependencyResolver=
新的旋转变压器(内核);
返回内核;
}
这就是我注册要使用的对象的方式:
私有静态无效注册服务(IKernel内核)
{
kernel.Bind().ToMock();
kernel.Bind().ToSelf();
}
虽然我没有测试控制器本身,但我确实希望调用它的适当实例,这就是为什么我要将它绑定到self。我必须承认,我认为这是正确的。这是一个测试示例:
public void UserCannotLogin()
{
System.Net.Http.HttpClient客户端=
新系统.Net.Http.HttpClient(服务器);
string json=string.Format(
“{{\”用户名\“:\”{0}\”,“\”密码\“:\”{1}\“}}”,
“错”、“错”);
HttpRequestMessage请求=
CreateRequest(@“api/auth/token”,json,HttpMethod.Get);
Action Action=()=>client.sendaync(请求);
使用(var response=client.sendaync(request.Result)
{
response.StatusCode.Should()
.Be(HttpStatusCode.Unauthorized);
}
}
我基本上得到了一个404错误。当我调试它时,它确实会转到我的DelegatingHandler
,但不会转到我的控制器
我觉得我基本上错过了一点,甚至可能不可能做我想做的事,但是如果有人对如何做这件事有任何建议,或者有不同的方法来实现同样的事情,我洗耳恭听
更新我认为这是因为MockingKernel
的默认行为是提供一个Mock,除非另有说明,所以它返回一个IHttpControllerSelector
的Mock。我现在已经设置了两个默认值:
kernel.Bind()
.To();
kernel.Bind()
.To();
我认为它仍然不起作用,因为没有指定格式化程序。明天我会试试,看看这是否能让我达到目的。好吧,我认为我说我基本上没有抓住要点是正确的,但我会回答这个问题,以防它能帮助其他人避免同样的错误 我认为,Ninject
MockingKernel
主要是关于自动模拟的,所以如果你有很多接口,你不关心它们在测试中是如何设置的,你可以在测试中忽略它们,它们会自动为你创建
在WebAPI的情况下,情况绝对不是这样,因为您不希望控制器选择器类被自动模拟,否则就不会调用控制器
因此,我提出的解决方案是坚持使用标准的Ninject内核
,然后将接口绑定到一个常量模拟对象:
kernel.Bind<IUserManager>().ToConstant(CreateUserManager());
private IUserManager CreateUserManager()
{
Mock<IUserManager> userManager = new Mock<IUserManager>();
// Set up the methods you want mocked
return userManager.Object;
}
kernel.Bind().ToConstant(CreateUserManager());
专用IUserManager CreateUserManager()
{
Mock userManager=new Mock();
//设置要模拟的方法
返回userManager.Object;
}
这样,我就能够成功地编写测试,使用HttpClient调用内存中的HttpServer,成功地调用我的DelegatingHandler
,然后到达我的控制器