C# 如何在c中使用nunit模拟控制器以使控件命中模型绑定器#
我试图模拟我的控制器来测试模型状态是否无效,如果模型状态无效,单元测试基本上返回400错误。 但是模型状态在模型绑定器的BindModel()方法中进行验证。 通过单元测试,我无法找到BindModel()方法 我有一个模拟控制器方法的通用方法,如下所示:C# 如何在c中使用nunit模拟控制器以使控件命中模型绑定器#,c#,nunit,C#,Nunit,我试图模拟我的控制器来测试模型状态是否无效,如果模型状态无效,单元测试基本上返回400错误。 但是模型状态在模型绑定器的BindModel()方法中进行验证。 通过单元测试,我无法找到BindModel()方法 我有一个模拟控制器方法的通用方法,如下所示: public static async Task<HttpResponseMessage> MockController<T, TReturn>( this T controller, Func<
public static async Task<HttpResponseMessage> MockController<T,
TReturn>(
this T controller, Func<T, Task<TReturn>> func, string requestUri =
"http://tempuri.org", HttpMethod httpMethod = null) where T : ApiController
{
using (var request = new HttpRequestMessage(httpMethod ?? HttpMethod.Get, new Uri(requestUri)))
{
controller.Request = request;
var actionResult = await func.Invoke(controller);
// Create the response from the action result
if (typeof(IHttpActionResult).IsAssignableFrom(typeof(TReturn)))
{
return await ((IHttpActionResult)actionResult).ExecuteAsync(CancellationToken.None);
}
else
{
return await Task.FromResult(request.CreateResponse(actionResult));
}
}
}
我应该在MockController方法中做什么更改来调用正在传递的控制器类的BindModel方法
型号活页夹
public class MyModelBinderProvider : ModelBinderProvider
{
public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
{
return new MyModelBinder();
}
}
public class MyModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var requestJson = actionContext.Request.Content.ReadAsStringAsync().Result;
var domain = actionContext.ActionArguments["domain"].ToString();
try
{
var model = Configuration.Load(requestJson);
bindingContext.Model = model;
domain = Map.GetEntityName(domain.Replace('-', '_'));
var invalidReqFieldsDict = RequestValidator.Validate(domain, model);
if (invalidReqFieldsDict.Any())
{
var exceptionMessage = String.Join("", invalidReqFieldsDict);
bindingContext.ModelState.AddModelError(bindingContext.ModelName, exceptionMessage);
return false;
}
return true;
}
catch (JsonException e)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, e.Message);
return false;
}
}
}
非常感谢您的帮助!
谢谢您应该直接针对ModelBinder编写单元测试。这比“通过”控制器进行测试更简单。显示如何卸载测试
BindModel()
,这就是您所需要的吗?@stuartd:controller方法返回无效模型的BadRequest,这是我需要通过控制器进行测试的。您可以向我们展示您的模型绑定器的源代码吗?如果您只需将逻辑移到逻辑层中,就会容易得多。MVC是一种表示模式,应该只包含表示/路由逻辑。这就是为什么测试如此困难的原因之一。如果有什么东西很难测试,你应该以此为线索,它没有正常工作,通常这意味着它没有遵守单一责任原则。你也应该问问自己,我在这里测试什么,为什么?如果测试MVC/HTTP/binding是在浪费时间,那么只测试逻辑应该直接针对ModelBinder编写单元测试。这比“通过”控制器进行测试更简单。显示如何卸载测试BindModel()
,这就是您所需要的吗?@stuartd:controller方法返回无效模型的BadRequest,这是我需要通过控制器进行测试的。您可以向我们展示您的模型绑定器的源代码吗?如果您只需将逻辑移到逻辑层中,就会容易得多。MVC是一种表示模式,应该只包含表示/路由逻辑。这就是为什么测试如此困难的原因之一。如果有什么东西很难测试,你应该以此为线索,它没有正常工作,通常这意味着它没有遵守单一责任原则。你也应该问问自己,我在这里测试什么,为什么?如果测试MVC/HTTP/binding是在浪费时间,那么只测试逻辑
public class MyModelBinderProvider : ModelBinderProvider
{
public override IModelBinder GetBinder(HttpConfiguration configuration, Type modelType)
{
return new MyModelBinder();
}
}
public class MyModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var requestJson = actionContext.Request.Content.ReadAsStringAsync().Result;
var domain = actionContext.ActionArguments["domain"].ToString();
try
{
var model = Configuration.Load(requestJson);
bindingContext.Model = model;
domain = Map.GetEntityName(domain.Replace('-', '_'));
var invalidReqFieldsDict = RequestValidator.Validate(domain, model);
if (invalidReqFieldsDict.Any())
{
var exceptionMessage = String.Join("", invalidReqFieldsDict);
bindingContext.ModelState.AddModelError(bindingContext.ModelName, exceptionMessage);
return false;
}
return true;
}
catch (JsonException e)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, e.Message);
return false;
}
}
}