【问题标题】:Unit testing asp.net mvc controller action tryupdate单元测试 asp.net mvc 控制器动作 tryupdate
【发布时间】:2012-09-09 18:06:11
【问题描述】:

我想测试控制器动作,但是Visual Studio代码覆盖工具没有覆盖一个点。

    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 可能会为假。你能帮忙吗?

【问题讨论】:

  • 老实说,我认为您不需要为该场景提供单元测试。我认为它应该是您编码调试和测试的一部分。在该示例中我可能会进行单元测试的唯一方法是 GetCityById()

标签: c# asp.net-mvc-3 unit-testing tdd code-coverage


【解决方案1】:

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

【讨论】:

  • 如果模型验证失败,TryUpdateModel 会返回 false,但我无法在单元测试中模拟模型验证错误的情况。
【解决方案2】:

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

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

现在您在派生类上调用 Activate 方法,除了模拟的 TryUpdateModel 方法外,该方法具有完全相同的功能,允许您测试所需的用例,而不会像如何模拟某个执行路径那样头疼.

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

【讨论】:

    【解决方案3】:

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

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

    使用适当的模拟,您可以根据需要隔离和测试行为。

    另外:我不同意@dreza 的评论...测试这种业务逻辑非常重要。

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-14
        • 1970-01-01
        • 2018-05-01
        • 1970-01-01
        • 2011-12-01
        • 1970-01-01
        相关资源
        最近更新 更多