如何使用 Moq 框架模拟 ModelState.IsValid?
我正在控制器操作方法中检查 ModelState.IsValid ,该方法创建一个如下所示的 Employee :
[HttpPost]
public virtual ActionResult Create(EmployeeForm employeeForm)
{
if (this.ModelState.IsValid)
{
IEmployee employee = this._uiFactoryInstance.Map(employeeForm);
employee.Save();
}
// Etc.
}
我想使用 Moq Framework 在我的单元测试方法中模拟它。我尝试像这样模拟它:
var modelState = new Mock<ModelStateDictionary>();
modelState.Setup(m => m.IsValid).Returns(true);
但这在我的单元测试用例中引发了异常。有人可以帮我吗?
I'm checking ModelState.IsValid
in my controller action method that creates an Employee like this:
[HttpPost]
public virtual ActionResult Create(EmployeeForm employeeForm)
{
if (this.ModelState.IsValid)
{
IEmployee employee = this._uiFactoryInstance.Map(employeeForm);
employee.Save();
}
// Etc.
}
I want to mock it in my unit test method using Moq Framework. I tried to mock it like this:
var modelState = new Mock<ModelStateDictionary>();
modelState.Setup(m => m.IsValid).Returns(true);
But this throws an exception in my unit test case. Can anyone help me out here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不需要嘲笑它。如果您已经有一个控制器,您可以在初始化测试时添加模型状态错误:
You don't need to mock it. If you already have a controller you can add a model state error when initializing your test:
我对上述解决方案的唯一问题是,如果我设置属性,它实际上不会测试模型。我这样设置我的控制器。
modelBinder对象是测试模型有效性的对象。这样我就可以设置对象的值并测试它。
The only issue I have with the solution above is that it doesn't actually test the model if I set attributes. I setup my controller this way.
The modelBinder object is the object that test the validity of the model. This way I can just set the values of the object and test it.
uadrive的回答让我明白了一部分,但仍然存在一些差距。如果
new NameValueCollectionValueProvider()
的输入中没有任何数据,模型绑定器会将控制器绑定到空模型,而不是model
对象。没关系,只需将模型序列化为
NameValueCollection
,然后将其传递到NameValueCollectionValueProvider
构造函数即可。嗯,不完全是。不幸的是,它在我的例子中不起作用,因为我的模型包含一个集合,并且NameValueCollectionValueProvider
与集合不能很好地配合。不过,
JsonValueProviderFactory
在这里发挥了作用。只要您指定内容类型“application/json”并将序列化的 JSON 对象传递到请求的输入流中,DefaultModelBinder
就可以使用它(请注意,因为这个输入流是一个内存流,所以可以不处理它,因为内存流不保留任何外部资源):uadrive's answer took me part of the way, but there were still some gaps. Without any data in the input to
new NameValueCollectionValueProvider()
, the model binder will bind the controller to an empty model, not to themodel
object.That's fine -- just serialise your model as a
NameValueCollection
, and then pass that into theNameValueCollectionValueProvider
constructor. Well, not quite. Unfortunately, it didn't work in my case because my model contains a collection, and theNameValueCollectionValueProvider
does not play nicely with collections.The
JsonValueProviderFactory
comes to the rescue here, though. It can be used by theDefaultModelBinder
as long as you specify a content type of"application/json
" and pass your serialised JSON object into your request's input stream (Please note, because this input stream is a memory stream, it's OK to leave it undisposed, as a memory stream doesn't hold on to any external resources):