正确测试某个方法在某些情况下什么都不做
Correctly testing that a method does nothing under certain cicrumstances
我的单元测试代码和 SonarQube 运行 有点麻烦。
我有以下简单测试:
[TestMethod]
public void TestFormat_Null()
{
_sut.Format(null);
}
public void Format(IPhone phoneNumber)
{
if (phoneNumber == null) return;
FormatNumber(phoneNumber);
FormatAreaCode(phoneNumber);
FormatCountryCode(phoneNumber);
}
这里的要求是,如果传入 null,该方法将什么都不做,因为没有要格式化的东西,也不会因异常而崩溃。
现在我们遇到的问题是我们的 SonarQube 抱怨说这是一个没有任何断言的测试。
有没有更好的方法来声明一个测试,该测试测试一个没有做任何事情的方法,或者在这种情况下应该简单地忽略 SonarQube 警告?
没有失败(并且不是不确定的)的测试就是通过的测试。
一些测试库如 NUnit 包括“Assert.DoesNotThrow”,其他的则不包括,如 MsTest 和 xUnit。从技术上讲,在每个测试结束时已经有一个隐式 Assert.DoesNotThrow。
我建议您考虑一下这里正在测试的内容。如果你传递 null 那么 SUT 会发生什么?它是否将某些 属性 设置为 null 或空字符串,谁使用了 属性?当然,Format() 确实 做了一些事情!
因此,如果我们通过查看它们的 return 值来测试纯函数,我们可以通过查看它们的实际作用来测试 void 方法——它们的 副作用 .
[TestMethod]
public void TestFormat_Null()
{
_sut.Format(null);
Assert.equal(string.empty, _sut.PrintInputText())
}
这可能证明是一个更有价值的测试,比像 Assert.True(true) 这样的变通方法更好......并且也许证明 SonarCube 的警告毕竟仍然有用。
我在 FluentAssertions 中找到了解决方案。
我的新代码将对 _sut 的旧调用包装在一个操作中,并使用 Fluent Assertions Should Not Throw 机制。
这是一个优雅的解决方案,因为我们已经在使用 FluentAssertions。我只是从来没有意识到它提供的 Should Not Throw 断言。直到现在我才知道 Should Throw。
我的单元测试代码和 SonarQube 运行 有点麻烦。
我有以下简单测试:
[TestMethod]
public void TestFormat_Null()
{
_sut.Format(null);
}
public void Format(IPhone phoneNumber)
{
if (phoneNumber == null) return;
FormatNumber(phoneNumber);
FormatAreaCode(phoneNumber);
FormatCountryCode(phoneNumber);
}
这里的要求是,如果传入 null,该方法将什么都不做,因为没有要格式化的东西,也不会因异常而崩溃。
现在我们遇到的问题是我们的 SonarQube 抱怨说这是一个没有任何断言的测试。
有没有更好的方法来声明一个测试,该测试测试一个没有做任何事情的方法,或者在这种情况下应该简单地忽略 SonarQube 警告?
没有失败(并且不是不确定的)的测试就是通过的测试。
一些测试库如 NUnit 包括“Assert.DoesNotThrow”,其他的则不包括,如 MsTest 和 xUnit。从技术上讲,在每个测试结束时已经有一个隐式 Assert.DoesNotThrow。
我建议您考虑一下这里正在测试的内容。如果你传递 null 那么 SUT 会发生什么?它是否将某些 属性 设置为 null 或空字符串,谁使用了 属性?当然,Format() 确实 做了一些事情!
因此,如果我们通过查看它们的 return 值来测试纯函数,我们可以通过查看它们的实际作用来测试 void 方法——它们的 副作用 .
[TestMethod]
public void TestFormat_Null()
{
_sut.Format(null);
Assert.equal(string.empty, _sut.PrintInputText())
}
这可能证明是一个更有价值的测试,比像 Assert.True(true) 这样的变通方法更好......并且也许证明 SonarCube 的警告毕竟仍然有用。
我在 FluentAssertions 中找到了解决方案。
我的新代码将对 _sut 的旧调用包装在一个操作中,并使用 Fluent Assertions Should Not Throw 机制。
这是一个优雅的解决方案,因为我们已经在使用 FluentAssertions。我只是从来没有意识到它提供的 Should Not Throw 断言。直到现在我才知道 Should Throw。