【问题标题】:Unit Testing: Reasons a ViewResult would be null, and why is it worth testing for?单元测试:ViewResult 为空的原因,为什么值得测试?
【发布时间】:2015-05-25 17:12:42
【问题描述】:

其他提到 null ViewResults 的问题实际上似乎是指 null 模型(我确实计划测试的东西)。我是全新的测试。今天刚开始我的第一个使用 TDD 的项目。我找到的一些资源,甚至是新 MVC 项目的股票测试代码,都显示测试 ViewResult 是否为空:

// Stock code
[TestMethod]
public void Index()
{
    // Arrange
    HomeController controller = new HomeController();

    // Act
    ViewResult result = controller.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(result);
}

我想知道为什么这是必要的。鉴于我的经验有限,我只能想到 ViewResult 为空的两个原因:

原因 1:您返回了错误的类型,例如 JsonResult 或其他东西 - 如果方法返回一般的 ActionResult,则可以做到这一点。我可以看到这是一个合法的原因,但我不确定这是我的方法需要专门返回 ViewResult 的要求。事实上,也许我希望它在未来很容易改变。

原因 2:您明确返回 null。但在现实世界中,你为什么要这样做?

有人可以提供其他示例来说明 ViewResult 何时为空,并解释为什么(或为什么不)测试很重要?正如我所说,我的经验是有限的,所以可能会有一些我没有看到的东西——这就是我问的原因。



编辑
如果我的问题格式不正确,我深表歉意。让我澄清一下:我理解如果它为 null 是不好的,并且理解测试 null 如果 null 是可能的/可能的价值。我更关心 A. 如何/为什么 首先它会为 null,以及 B. 这些原因是否是可以增加测试价值的合法原因,或者它们是否不太可能是边缘情况在现实世界中永远发生。

我的原因 1 和原因 2 是否涵盖了所有场景?如果没有,还有什么其他的?如果它们是极端情况,极不可能发生,您是否仍对其进行测试?

【问题讨论】:

  • understand the value in testing for null if nulls are possible/likely - 所以,你是说如果 null 不太可能,不应该有一个 null check 测试用例?这样想 - null check 测试用例本身传达 null 不太可能。
  • @YK1 你是说测试表明一个不太可能的错误?但是你不会也测试可能、容易犯的错误吗?难道这些测试不会比测试开发人员一开始就不会犯的错误更有价值吗?您的解释似乎是,如果有任何不应该的东西可以为空,请测试以确保它不是,时期-这很可能是做事的正确方法,没有争议,我只是在印象测试因为极不可能的错误是过度做事/“为了测试而测试”,而不是增加真正的价值。
  • 这就是为什么我的问题集中在发生错误的可能性有多大,以及为什么我真正要寻找的是会导致错误的场景。然而,共识似乎是,我的印象是不正确的,无论多么不可能,你都应该测试每一个场景。
  • But would you not also test for likely, easy-to-make mistakes?。当然我们应该测试那些。 Your interpretation seems to be that if anything is nullable that shouldn't be, test to make sure it isn't, period - 此解释适用于该 特定 测试用例,正如您所提到的,它也是默认股票测试代码的一部分。如果您有可能为 null,那么您将没有此测试用例,您将有不同的测试用例来适应可能为 null 的情况。
  • testing for highly unlikely mistakes is overdoing things- 一般来说,我会反过来说。您对极不可能的情况进行的测试越多,您的测试套件就越坚固。在您的特定情况下,您会说开发人员必须非常愚蠢才能返回空视图 - 极不可能。那么,还有其他情况,例如硬件故障、网络延迟、可扩展性 - 确实这些东西很难用单元测试来测试。

标签: c# unit-testing asp.net-mvc-5


【解决方案1】:

谁能给出 ViewResult 何时为空的其他示例

它应该永远null,这就是这个测试用例所验证的。如果开发人员以某种方式返回 null 在控制器代码中引入错误,则此测试用例将失败,并在错误代码投入生产之前挽救大量生命。

【讨论】:

    【解决方案2】:

    测试的重点是双重的。在进行测试驱动开发时,它们会驱动您的代码开发。您编写了一个断言返回的视图不为空的测试。这个测试一开始会失败,直到你写出满足它的代码。

    第二步是在代码发生变化并返回 null 时发出警告。

    从现在起 2 年后,您可能会更改方法以添加更复杂的逻辑,从而意外导致 null 返回。你想马上抓住它。

    【讨论】:

    • 虽然我仍然想知道会导致空返回的特定场景,但您的答案最接近,因为您提到需要检查 TDD 的第一步 - 我忘记了这部分,因为它是库存生成的方法/单元测试,然后我正在修改(主页/索引,因此代码已经存在以使测试通过)。
    • @user2607389 - 很难说会是什么场景。但是我有一个例子是我会根据其他值查找要返回的视图。从理论上讲,应该总是存在返回视图的情况,但是我的代码中可能存在错误...关键是,返回的视图是引用类型..它可能为 Null,因此它应该检查以防它发生变化。
    • 感谢您的示例 - 这确实是我没有想到的一个非常真实的可能性。无论如何,要始终检查所有可为空的类型的经验教训。
    【解决方案3】:

    几乎我们针对控制器操作编写的每个测试都会确保返回的 ActionResult(无论是 ViewResult、RedirectResult 等)检查以确保它不为空。这与确保它不为空无关,而与后续断言有关。例如,假设您的测试看起来像这样。

    [TestMethod]
    public void Index()
    {
        HomeController controller = new HomeController();
    
        ViewResult result = controller.Index() as ViewResult;
    
        Assert.IsNotNull( result.Model );
    }
    

    如果在您尝试取消引用它以获取 Model 属性时结果为 null,则会抛出 NullReferenceException。您的测试会失败,但它会失败并引发异常。现在开发人员必须弄清楚什么引用是空的。对我们而言,这实际上只是一种确保您在尝试使用返回的结果时不会在代码中遇到难以调试的故障的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      相关资源
      最近更新 更多