在一个asp.net核心应用程序,我有一对控制器方法响应编辑操作。一个GET,这需要一个字符串参数为实体ID:asp.net核心mvc控制器单元测试时使用TryUpdateModel
public async Task<IActionResult> Edit(string id)
,另一个用于接收更新的实体值的POST:
[HttpPost]
[ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditSave(string id)
里面的过帐操作方法,我称之为
var bindingSuccess = await TryUpdateModelAsync(vm);
而且工作正常。
现在,我试图为此编写一个测试,但我发现TryUpdateModelAsync
需要从HttpContext
和控制器充实大量的东西。我试着嘲笑这些,但在查看TryUpdateModelAsync
的源代码后,我意识到我基本上需要将所有东西都嘲弄到元数据,而这并不是简单明了的。
我想知道是否这个难题告诉了我一些事情:TryUpdateModelAsync
使它很难测试,所以我应该重构控制器方法而不依赖这个帮助器。相反,我可以为我的viewmodel的方法添加另一个参数,并使用[FromBody]
对其进行装饰,因此模型绑定在发布时会从发布字段发生,但在测试时我可以传入视图模型。但是,我喜欢TryUpdateModelAsync
方法,因为它会将post字段合并到我的视图模型中。另一种我能想到完成合并的方式是编写我自己的Merge方法。好吧,没什么大不了的,但我宁愿不必为每个实体做这件事(或者重新开始编写基于反思的合并),真的,我想知道我是否错过了如何编写一个单元对此进行测试。我可以启动整个TestServer
,就像我为集成测试所做的那样,但我不确定这是否是正确的方向,感觉就像我会进一步复杂化单元测试一样。但是,在这种情况下,这可能是合理的吗?
我已经看到了与以前版本的.NET MVC的,所有他们需要做的是模拟一个IValueProvider
并将其连接到控制器,但在.NET的核心它出现在TryUpdateModelAsync
被重新设计,并需要更多的工作答案移动部件。
总之,我看到三个选项:
- 继续嘲讽和删空所有的作品是
TryUpdateModelAsync
需求。这可能是一个死路一条,似乎到目前为止是 。 - 使用
TestServer
和使用HttpClient
- 重构这个方法来通过侧跨 在视图模型参数使用
[FromBody]
,然后我自己写的合并 方法为每个实体,也使从一个小 更高的高度本次测试TryUpdateModelAsync
这些都有它们的缺点,所以我希望列表中有第四个条目,因为我是无知的,所以我没有看到。
嗯,我喜欢这样的解决方案 - 如果你需要模拟它,包起来并注入。我同意,ControllerBase不能很好地遵守显式依赖关系。我去了另一个方向,并充实了HttpContext,并在没有抛出异常的情况下遇到了一个问题,但模型没有更新。我会留下另一个不同的问题。这似乎提供了一个可行的第四选择:) – Erikest