0

我想测试控制器动作,但视觉工作室代码覆盖工具没有覆盖一点。

    public ActionResult Activate(int? id)
    {
        if (id == null)
            return View("PageNotFound");

        var city = repository.GetCityById(id.Value);

        if (city == null)
            return View("PageNotFound");


        city.IsActive = !city.IsActive;

        if (TryUpdateModel(city))
        {
            repository.Save();
            return RedirectToAction("MyCities");
        }

        ***return View("PageNotFound");***
    }

在代码覆盖率中,* return View("PageNotFound");*不包括在内。因为,我无法模拟 TryUpdateModel 错误的情况。如果模型无法更新,TryUpdateModel 可能会为假。你能帮忙吗?

4

4 回答 4

0

TryUpdateModel如果模型验证失败,将返回 false。
(在这种情况下,您不应显示未找到的页面)

于 2012-09-09T18:15:47.357 回答
0

好的,我解决了解决方案。我删除了 TryUpdatemodel if 条件。直接使用repository.Save() 方法。因为我没有发送参数模型来激活方法。

于 2012-09-17T17:55:08.247 回答
0

在这样的情况下,您有各种选择。其中之一是创建一个覆盖您要控制的方法的实际功能的存根。

例如,您可以声明TryUpdateModel为虚拟的。在您的单元测试中,您继承它并覆盖 TryGetModel 以简单地返回 false,而不是使用原始类。所有其他功能保持原样。

现在,您Activate在派生类上调用具有与模拟方法完全相同的功能的TryUpdateModel方法,允许您测试所需的用例,而不会因为如何模拟某个执行路径而费尽心思。

这种技术并非没有缺点:它使您仅出于测试目的将该方法声明为虚拟方法,从而防止您将其设为密封或静态。还有其他更高级的技术(模拟对象隔离框架),但我认为这对于这种情况来说是一个足够好的解决方案。

于 2012-09-09T18:58:41.727 回答
0

您没有包含代码来显示如何处理货物依赖项的生命周期,所以我只是在猜测,但是......

作为测试设置的一部分,应该可以将此类的模拟或假实例传递给控制器​​(如果当前不可行,请重构直到可行)。

有了模拟,您可以根据需要隔离和测试行为。

旁白:我不同意@dreza 的评论……测试这种业务逻辑非常重要。

我还警告不要按照@Vitaliy 的建议伪造 TryUpdateModel 的实现,毕竟你想测试如果货物模型无效会发生什么(不仅仅是通过提供新版本的核心代码来假装它是)。

于 2012-09-10T07:56:49.363 回答