2012-09-09 55 views
0

我想测试控制器的动作,但有一点不被visual studio代码覆盖工具覆盖。单元测试asp.net mvc控制器动作tryupdate

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");*** 
    } 
代码覆盖率

*返回查看( “PageNotFound”); *未被覆盖。 因为,我无法模拟TryUpdateModel错误stuStation。如果模型无法更新,TryUpdateModel可能会变为false。你能帮忙吗?

+0

说实话,我不认为你需要提供该场景的单元测试。我认为它应该是你的代码调试和测试的一部分。我可能会在该示例中单元测试的唯一方法是GetCityById() – dreza

回答

0

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

+0

如果模型验证失败,则TryUpdateModel将返回false,但我无法在单元测试中模拟模型验证错误stutry。 – bayramucuncu

0

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

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

现在你骂上从模拟TryUpdateModel方法具有完全相同的功能分开,让你没有打破你的头如何模拟确定执行路径测试所需的用例派生类中的方法Activate

这种技术并非没有缺点:它使得您只将方法声明为虚拟的,仅用于测试目的,从而防止您将其封闭或静态化。还有其他更先进的技术(Mock objects,isolation frameworks),但我认为这对于此场景来说已经足够好了。

0

你不包括代码来显示如何在货物依赖的寿命的处理,所以我只是猜测,但是...

应该可以通过一个模拟的或假的实例作为测试设置的一部分(如果目前不可能,重构直到它)。

随着模拟到位,您可以根据需要分离和测试行为。

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

我也奉劝不要伪造TryUpdateModel的执行情况@Vitaliy的建议,毕竟你想测试一下如果货物模型是无效的(不只是假装它是通过提供核心的新版本码)。

+0

我编辑货物为城市 – bayramucuncu

0

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