C# 如何在c中使用nunit模拟控制器以使控件命中模型绑定器#

C# 如何在c中使用nunit模拟控制器以使控件命中模型绑定器#,c#,nunit,C#,Nunit,我试图模拟我的控制器来测试模型状态是否无效,如果模型状态无效,单元测试基本上返回400错误。 但是模型状态在模型绑定器的BindModel()方法中进行验证。 通过单元测试,我无法找到BindModel()方法 我有一个模拟控制器方法的通用方法,如下所示: public static async Task<HttpResponseMessage> MockController<T, TReturn>( this T controller, Func<

我试图模拟我的控制器来测试模型状态是否无效,如果模型状态无效,单元测试基本上返回400错误。 但是模型状态在模型绑定器的BindModel()方法中进行验证。 通过单元测试,我无法找到BindModel()方法

我有一个模拟控制器方法的通用方法,如下所示:

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;
                }
            }
        }