我正在为此返回“ void”的方法编写单元测试。我希望有一种情况,即在没有引发异常的情况下测试通过。如何用C#编写?
Assert.IsTrue(????)
(我的猜测是这是我应该检查的方式,但是“ ???”中有什么内容)
我希望我的问题足够清楚。
我正在为此返回“ void”的方法编写单元测试。我希望有一种情况,即在没有引发异常的情况下测试通过。如何用C#编写?
Assert.IsTrue(????)
(我的猜测是这是我应该检查的方式,但是“ ???”中有什么内容)
我希望我的问题足够清楚。
Answers:
如果抛出异常,您的单元测试无论如何都会失败-您不需要放入特殊的断言。
这是您将看到根本没有断言的单元测试的少数情况之一-如果引发异常,则测试将隐式失败。
但是,如果您确实确实想为此编写一个断言-也许能够捕获异常并报告“没有异常但得到了此...”,则可以执行以下操作:
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(以上是NUnit的示例,但对于MSTest同样适用)
在NUnit中,您可以使用:
Assert.DoesNotThrow(<expression>);
断言您的代码不会引发异常。尽管即使没有声明也抛出异常会导致测试失败,但是这种方法的价值在于您可以区分未满足的期望和测试中的错误,并且可以选择添加一条自定义消息,将显示在您的测试输出中。措辞井井有条的测试输出可以帮助您找到导致测试失败的代码错误。
我认为添加测试以确保您的代码不会引发异常是有效的。例如,假设您正在验证输入,并且需要将输入的字符串转换为long。有时字符串为null,这是可以接受的,因此您要确保字符串转换不会引发异常。因此,将有代码来处理这种情况,并且如果您还没有编写测试,那么您将缺少重要逻辑的内容。
public class TestBase { //believe me, I don't like this anymore than you do. protected void AssertDoesNotThrow(Action action, string message) { try { action(); } catch (Exception) { Assert.Fail(message); } } }
不要测试不会发生什么。就像确保代码不会中断一样。这有点暗示,我们都在努力开发不间断的,无错误的代码。您要为此编写测试吗?为什么只是一种方法?您是否不希望所有方法都经过测试以确保它们不会引发任何异常?遵循这条路,您将对代码库中的每个方法进行一次额外的,虚拟的,无需声明的测试。它没有任何价值。
当然,如果您的要求是验证方法是否捕获到异常,则可以进行测试(或将其反转一点;测试它不会抛出应捕获的内容)。
但是,一般的方法/做法仍然完好无损-您不会针对某些超出测试代码范围的人为/模糊的要求编写测试(并且测试“有效”或“不抛出”通常是这样-特别是在方法的职责众所周知的情况下)。
简而言之-专注于代码必须执行的操作并为此进行测试。
此类帮助器类使我对MSTest感到不满。也许它也会刮伤您的。
[TestMethod]
public void ScheduleItsIneligibilityJob_HasValid_CronSchedule()
{
// Arrange
var factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
// Assert
AssertEx.NoExceptionThrown<FormatException>(() =>
// Act
_service.ScheduleJob(scheduler)
);
}
public sealed class AssertEx
{
public static void NoExceptionThrown<T>(Action a) where T:Exception
{
try
{
a();
}
catch (T)
{
Assert.Fail("Expected no {0} to be thrown", typeof(T).Name);
}
}
}
Assert
已经过时了,但是具有单例属性访问器,That
可以将其用作扩展方法的挂钩。拥有Assert.That.DoesNotThrow()
而不是可能更整洁,更容易发现AssertEx.DoesNotThrow()
。这只是一个意见。
我希望Assert.Whatever
在每次测试结束时都能看到一个,只是为了保持一致性……如果没有,我真的可以确定那里不应该有一个吗?
对我来说,这就像放 Assert.IsTrue(true);
我知道我不是无意间将代码放在那里,因此我应该有足够的信心快速浏览一下这是预期的。
[TestMethod]
public void ProjectRejectsGappedVersioningByDefault() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
Assert.Throws<ScriptProject.InvalidProjectFormatException>(() => {
var sut = new ScriptProject(files);
});
}
[TestMethod]
public void ProjectAcceptsGappedVersionsExplicitly() {
var files = new List<ScriptFile>();
files.Add(ScriptProjectTestMocks.GetVersion1to2());
files.Add(ScriptProjectTestMocks.GetVersion3to4());
var sut = new ScriptProject(files, true);
Assert.IsTrue(true); // Assert.Pass() would be nicer... build it in if you like
}
我的朋友Tim告诉我有关ExpectedException的信息。我真的很喜欢这个b / c,它更简洁,更少的代码,并且非常明确地表明您正在测试异常。
[TestMethod()]
[ExpectedException(typeof(System.Exception))]
public void DivideTest()
{
int numerator = 4;
int denominator = 0;
int actual = numerator / denominator;
}
您可以在此处详细了解它:ExpectedException Attribute Usage。