【问题标题】:How to test if function does not throw exception? [duplicate]如何测试函数是否不抛出异常? [复制]
【发布时间】:2016-06-16 17:21:11
【问题描述】:

我有这个功能并测试:

public void SaveForWeb ()
{
    UpdateGameState();
    try
    {
        PlayerPrefs.SetFloat(Helper.EXP_KEY, experience);
        PlayerPrefs.SetFloat(Helper.SCORE_KEY, score);
        // other properties that need to be saved in PlayerPrefs

        PlayerPrefs.Save();
    }
    catch (Exception ex)
    {
        Debug.Log(ex.Message);
    }
}

[Test]
[Category(Helper.TEST_CATEGORY_SAVE_FOR_WEB)]
public void SaveForWebTest ()
{
    // arrange
    var slgdController = FakeSaveLoadGameDataController();
    TestDelegate myDelegate = () => {};

    // act
    slgdController.SaveForWeb();

    // assert
    Assert.DoesNotThrow(myDelegate);
}

但我觉得断言和SaveForWeb()函数的调用之间没有联系。

注意:SaveForWeb() 使用 Unity3D API 中的 PlayerPrefs,如果本地文件超过 1 MB,可能会抛出 PlayerPrefsException。

如果函数不抛出异常,这是断言的正确方法吗?

【问题讨论】:

  • 你不需要断言一个函数在单元测试中不会抛出异常。默认情况下,如果在单元测试中抛出异常,则单元测试将由于意外异常而失败。
  • 是的,它是重复的,但没关系,Unity3D 社区的某些人可能会觉得它很有用。
  • 如果有用(并且可能是无辜的)重复没有错:p

标签: c# unit-testing exception nunit nsubstitute


【解决方案1】:

如果它没有抛出异常,您的代码应该可以正常工作并到达测试方法的末尾。所以你可以在末尾添加一个Assert.IsTrue(true),它只被称为 if 方法运行没有任何错误。否则(如果发生异常)测试将立即停止并返回 false。

编辑:您甚至不需要调用Assert.IsTrue,如果测试结束,测试也会成功。

【讨论】:

  • 所以你想说如果 SaveForWeb() 抛出异常,它会在中断的那一行停止测试的执行?
  • 是的,如果发生异常,测试将立即停止并返回 false。
【解决方案2】:

正如其他人所提到的,单元测试将自动失败。但是,如果您确实想为此编写断言,请尝试这样的操作。

[Test]
[Category(Helper.TEST_CATEGORY_SAVE_FOR_WEB)]
public void SaveForWebTest ()
{
    // arrange
    var slgdController = FakeSaveLoadGameDataController();
    TestDelegate myDelegate = () => {};

    // act
    try
    {
        slgdController.SaveForWeb();
        Assert.IsTrue(true) // Not Actually necessary as should still pass
    }
    catch (Exception ex)
    {
        Assert.Fail("Expected no exception, but got: " + ex.Message);
    }
}

【讨论】:

    【解决方案3】:

    在我的测试中,我只是不做任何断言。如果抛出异常,则测试将失败,因为您没有 ExpectedException 属性左右。

    Assert.IsTrue(true) 没有意义恕我直言

    【讨论】:

      【解决方案4】:

      如果方法没有抛出,你不必断言。我知道你在使用 NUnit,但是有一个 xUnit issue 描述了为什么你不需要断言它。

      但是,如果你想明确一点,你可以这样做:

      [Test]
      [Category(Helper.TEST_CATEGORY_SAVE_FOR_WEB)]
      public void SaveForWebTest ()
      {
          // arrange
          var slgdController = FakeSaveLoadGameDataController();
      
          Assert.DoesNotThrow(() => slgdController.SaveForWeb());
      }
      

      【讨论】:

      • 其他一些答案有效,但这种方法在失败时会给出最好的错误消息。
      【解决方案5】:

      你应该给你的单元测试起更有意义的名字。这样,您实际上可以从测试中了解出了什么问题:

          [TestMethod]
          public void SaveForWeb_WhenGameControllerIsOk_DoesNotThrowException()
          {
              // Arrange
              var controller = FakeSaveLoadGameDataController();
      
              // Act
              controller.SaveForWeb();
      
              // Assert - Will fail by exceptionThrown
          }
      
          [TestMethod, ExpectedException(typeof(ReallyBadException))]
          public void SaveForWeb_WhenGameControllerThrowsException_ThrowsException()
          {
              // Arrange
              var controller = new FakeSaveLoadGameDataControllerWithException();
      
              // Act
              controller.SaveForWeb();
          }
      

      【讨论】:

        猜你喜欢
        • 2019-11-26
        • 2012-11-19
        • 1970-01-01
        • 2021-02-26
        • 1970-01-01
        • 2021-10-28
        • 2015-06-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多