I'm writing a unit test for this one method which returns "void". I would like to have one case that the test passes when there is no exception thrown. How do I write that in C#?
我正在为这个返回“void”的方法编写一个单元测试。我希望有一个案例,当没有异常抛出时,测试通过。我如何用C#编写?
Assert.IsTrue(????)
(My guess is this is how I should check, but what goes into "???")
(我的猜测是这是我应该检查的,但是什么进入“???”)
I hope my question is clear enough.
我希望我的问题很清楚。
5 个解决方案
#1
94
Your unit test will fail anyway if an exception is thrown - you don't need to put in a special assert.
如果抛出异常,你的单元测试无论如何都会失败 - 你不需要输入特殊的断言。
This is one of the few scenarios where you will see unit tests with no assertions at all - the test will implicitly fail if an exception is raised.
这是少数情况下您将看到完全没有断言的单元测试的情况之一 - 如果引发异常,测试将隐式失败。
However, if you really did want to write an assertion for this - perhaps to be able to catch the exception and report "expected no exception but got this...", you can do this:
但是,如果你真的想为此写一个断言 - 也许是为了能够捕获异常并报告“预期没有例外但得到了这个......”,你可以这样做:
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(the above is an example for NUnit, but the same holds true for MSTest)
(以上是NUnit的示例,但MSTest也是如此)
#2
17
In NUnit, you can use:
在NUnit中,您可以使用:
Assert.DoesNotThrow(<expression>);
to assert that your code does not throw an exception. Although the test would fail if an exception is thrown even if there was no Assert around it, the value of this approach is that you can then distinguish between unmet expectations and bugs in your tests, and you have the option of adding a custom message that will be displayed in your test output. A well-worded test output can help you locate errors in your code that have caused a test to fail.
断言你的代码不会抛出异常。虽然如果抛出异常,即使周围没有Assert,测试也会失败,但这种方法的价值在于您可以区分测试中未满足的期望和错误,并且您可以选择添加自定义消息将显示在您的测试输出中。一个措辞良好的测试输出可以帮助您找到代码中导致测试失败的错误。
I think it's valid to add tests to ensure that your code is not throwing exceptions; for example, imagine you are validating input and need to convert an incoming string to a long. There may be occasions when the string is null, and this is acceptable, so you want to ensure that the string conversion does not throw an exception. There will therefore be code to handle this occasion, and if you haven't written a test for it you will be missing coverage around an important piece of logic.
我认为添加测试以确保您的代码不会抛出异常是有效的;例如,假设您正在验证输入并需要将传入的字符串转换为long。有时字符串为null,这是可以接受的,因此您需要确保字符串转换不会引发异常。因此会有代码来处理这种情况,如果你没有为它编写测试,你将会遗漏一个重要逻辑的覆盖范围。
#3
10
Don't test that something doesn't happen. It's like assuring that code doesn't break. That's sort of implied, we all strive for non-breaking, bug-less code. You want to write tests for that? Why just one method? Don't you want all your methods being tested that they don't throw some exception? Following that road, you'll end up with one extra, dummy, assert-less test for every method in your code base. It brings no value.
不要测试不会发生的事情。这就像确保代码不会破坏一样。这有点暗示,我们都在争取不破坏,无错误的代码。你想为此编写测试吗?为什么只有一种方法?难道您不希望所有方法都经过测试,他们不会抛出异常吗?在这条道路之后,您将最终为代码库中的每个方法进行一次额外的,虚拟的,无断言的测试。它没有带来任何价值。
Of course, if your requirement is to verify method does catch exceptions, you do test that (or reversing it a bit; test that it does not throw what it is supposed to catch).
当然,如果您的要求是验证方法确实捕获异常,那么您可以测试(或者稍微反转一下;测试它不会抛出它应该捕获的内容)。
However, the general approach/practices remain intact - you don't write tests for some artificial/vague requirements that are out of scope of tested code (and testing that "it works" or "doesn't throw" is usually an example of such - especially in scenario when method's responsibilities are well known).
但是,一般方法/实践保持不变 - 您不会为超出测试代码范围的某些人为/模糊需求编写测试(并且测试“它工作”或“不抛出”通常是一个示例这样 - 特别是在方法的职责众所周知的情况下)。
To put it simple - focus on what your code has to do and test for that.
简单来说 - 专注于你的代码必须做什么并测试它。
#4
4
This helper class scratched my itch with MSTest. Maybe it can scratch yours also.
这个助手类用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);
}
}
}
#5
1
I like to see an Assert.Whatever
at the end of each test, just for consistency... without one, can I really be sure there's not supposed to be one there?
我喜欢看Assert。无论在每次测试结束时,只是为了保持一致......没有一个,我真的可以肯定那里不应该有吗?
For me, this is as simple as putting Assert.IsTrue(true);
对我来说,这就像放入Assert.IsTrue(true)一样简单;
I know I didn't accidentally put that code in there, and thus I should be confident enough at quick a skim through that this was as intended.
我知道我并没有意外地将那些代码放在那里,因此我应该有足够的信心快速浏览一下这是否符合预期。
[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
}
#1
94
Your unit test will fail anyway if an exception is thrown - you don't need to put in a special assert.
如果抛出异常,你的单元测试无论如何都会失败 - 你不需要输入特殊的断言。
This is one of the few scenarios where you will see unit tests with no assertions at all - the test will implicitly fail if an exception is raised.
这是少数情况下您将看到完全没有断言的单元测试的情况之一 - 如果引发异常,测试将隐式失败。
However, if you really did want to write an assertion for this - perhaps to be able to catch the exception and report "expected no exception but got this...", you can do this:
但是,如果你真的想为此写一个断言 - 也许是为了能够捕获异常并报告“预期没有例外但得到了这个......”,你可以这样做:
[Test]
public void TestNoExceptionIsThrownByMethodUnderTest()
{
var myObject = new MyObject();
try
{
myObject.MethodUnderTest();
}
catch (Exception ex)
{
Assert.Fail("Expected no exception, but got: " + ex.Message);
}
}
(the above is an example for NUnit, but the same holds true for MSTest)
(以上是NUnit的示例,但MSTest也是如此)
#2
17
In NUnit, you can use:
在NUnit中,您可以使用:
Assert.DoesNotThrow(<expression>);
to assert that your code does not throw an exception. Although the test would fail if an exception is thrown even if there was no Assert around it, the value of this approach is that you can then distinguish between unmet expectations and bugs in your tests, and you have the option of adding a custom message that will be displayed in your test output. A well-worded test output can help you locate errors in your code that have caused a test to fail.
断言你的代码不会抛出异常。虽然如果抛出异常,即使周围没有Assert,测试也会失败,但这种方法的价值在于您可以区分测试中未满足的期望和错误,并且您可以选择添加自定义消息将显示在您的测试输出中。一个措辞良好的测试输出可以帮助您找到代码中导致测试失败的错误。
I think it's valid to add tests to ensure that your code is not throwing exceptions; for example, imagine you are validating input and need to convert an incoming string to a long. There may be occasions when the string is null, and this is acceptable, so you want to ensure that the string conversion does not throw an exception. There will therefore be code to handle this occasion, and if you haven't written a test for it you will be missing coverage around an important piece of logic.
我认为添加测试以确保您的代码不会抛出异常是有效的;例如,假设您正在验证输入并需要将传入的字符串转换为long。有时字符串为null,这是可以接受的,因此您需要确保字符串转换不会引发异常。因此会有代码来处理这种情况,如果你没有为它编写测试,你将会遗漏一个重要逻辑的覆盖范围。
#3
10
Don't test that something doesn't happen. It's like assuring that code doesn't break. That's sort of implied, we all strive for non-breaking, bug-less code. You want to write tests for that? Why just one method? Don't you want all your methods being tested that they don't throw some exception? Following that road, you'll end up with one extra, dummy, assert-less test for every method in your code base. It brings no value.
不要测试不会发生的事情。这就像确保代码不会破坏一样。这有点暗示,我们都在争取不破坏,无错误的代码。你想为此编写测试吗?为什么只有一种方法?难道您不希望所有方法都经过测试,他们不会抛出异常吗?在这条道路之后,您将最终为代码库中的每个方法进行一次额外的,虚拟的,无断言的测试。它没有带来任何价值。
Of course, if your requirement is to verify method does catch exceptions, you do test that (or reversing it a bit; test that it does not throw what it is supposed to catch).
当然,如果您的要求是验证方法确实捕获异常,那么您可以测试(或者稍微反转一下;测试它不会抛出它应该捕获的内容)。
However, the general approach/practices remain intact - you don't write tests for some artificial/vague requirements that are out of scope of tested code (and testing that "it works" or "doesn't throw" is usually an example of such - especially in scenario when method's responsibilities are well known).
但是,一般方法/实践保持不变 - 您不会为超出测试代码范围的某些人为/模糊需求编写测试(并且测试“它工作”或“不抛出”通常是一个示例这样 - 特别是在方法的职责众所周知的情况下)。
To put it simple - focus on what your code has to do and test for that.
简单来说 - 专注于你的代码必须做什么并测试它。
#4
4
This helper class scratched my itch with MSTest. Maybe it can scratch yours also.
这个助手类用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);
}
}
}
#5
1
I like to see an Assert.Whatever
at the end of each test, just for consistency... without one, can I really be sure there's not supposed to be one there?
我喜欢看Assert。无论在每次测试结束时,只是为了保持一致......没有一个,我真的可以肯定那里不应该有吗?
For me, this is as simple as putting Assert.IsTrue(true);
对我来说,这就像放入Assert.IsTrue(true)一样简单;
I know I didn't accidentally put that code in there, and thus I should be confident enough at quick a skim through that this was as intended.
我知道我并没有意外地将那些代码放在那里,因此我应该有足够的信心快速浏览一下这是否符合预期。
[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
}