该单元测试中是否有太多断言?
这一单元测试中是否有太多断言?
[Fact]
public void Send_sends_an_email_message() {
using (var server = new MockSmtpServer()) {
server.Start();
using (var client = new EmailClient("localhost")) {
string from = "[email protected]";
IEnumerable<string> to = new[] { "[email protected]" };
string subject = "Test";
string body = "Test.";
client.Send(from, to, subject, body);
var session = server.Sessions.FirstOrDefault();
Assert.NotNull(session);
var message = session.Messages.FirstOrDefault();
Assert.NotNull(message);
Assert.NotNull(message.From);
Assert.Equal(message.From.Address, "[email protected]");
Assert.NotNull(message.To);
var recipient = message.To.FirstOrDefault();
Assert.NotNull(recipient);
Assert.Equal(recipient.Address, "[email protected]");
Assert.Equal(message.Subject, "Test");
Assert.Equal(message.Body, "Test.");
}
}
}
我认为这段代码不需要任何解释,但如果需要,请告诉我。
Are there too many asserts in this one unit test?
[Fact]
public void Send_sends_an_email_message() {
using (var server = new MockSmtpServer()) {
server.Start();
using (var client = new EmailClient("localhost")) {
string from = "[email protected]";
IEnumerable<string> to = new[] { "[email protected]" };
string subject = "Test";
string body = "Test.";
client.Send(from, to, subject, body);
var session = server.Sessions.FirstOrDefault();
Assert.NotNull(session);
var message = session.Messages.FirstOrDefault();
Assert.NotNull(message);
Assert.NotNull(message.From);
Assert.Equal(message.From.Address, "[email protected]");
Assert.NotNull(message.To);
var recipient = message.To.FirstOrDefault();
Assert.NotNull(recipient);
Assert.Equal(recipient.Address, "[email protected]");
Assert.Equal(message.Subject, "Test");
Assert.Equal(message.Body, "Test.");
}
}
}
I don't think this code requires any explanation, but if it does please let me know.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我尝试使我的单元测试保持相当小的规模并一次测试一件事。因此,我可能会将测试不同的部分放入单独的测试中,例如
sendWillSendAnEmail
、fromContainsSenderAddress
、toContainsRecipientAddress
、mailBodyContainsMailMessage
、mailContainsSubject
I try to keep my UnitTests fairly small and test one thing at a time. So I'd likely make testing distinct parts into separate tests, e.g.
sendWillSendAnEmail
,fromContainsSenderAddress
,toContainsRecipientAddress
,mailBodyContainsMailMessage
,mailContainsSubject
我认为它太大了。
当你有一堆较小的测试时,你可以获得“缺陷定位”——只需运行所有测试,你就可以准确地看到问题出在哪里。使用当前拥有的尽可能多的断言(并且没有断言消息),您可能必须启动调试器才能找到答案。请记住,您可能最终会进行数百甚至数千个测试,如果其中一堆测试失败,您不想调试每个测试来了解原因。
此外,任何在测试早期失败的断言都意味着后面的断言不会运行。当它们被分成单独的测试时,每个断言都会被检查。这是一种权衡;其中许多断言可能是相关的,并且会同时失败,因此您将有五个红色测试,而不是一个。但我的工作前提是信息越多越好,所以我宁愿进行这五个测试并知道所有五个断言都失败了。
I think it's too large.
When you have a bunch of smaller tests, you can get "defect localization" - just by running all the tests, you can see exactly where a problem is. With as many asserts as you currently have (and no assert messages) you'd probably have to launch a debugger to find out. Remember that you probably will end up having hundreds if not thousands of tests, and if a bunch of them are failing, you don't want to have to debug each one to see why.
Also, any assert failing early in the test means the later asserts are not run. When they're separated into individual tests, every assert is checked. This is sort of a trade-off; a lot of those asserts probably are related and will fail at the same time, so you'll have five red tests instead of one. But I work from the premise that more information is better, so I would rather have those five tests and know that all five asserts failed.
我认为你的断言没有特别的问题,但是如果你想清理你的代码,你可以更改
为
First()
无论如何都会抛出异常,所以只需更改你的代码你就可以获得以下好处:断言将使您无需那么多代码。您也可以在其他地方进行类似的更改。但作为一般规则,在单元测试中不要认为任何事情都是理所当然的——这意味着大量的断言!
I see no particular problem with your asserts, but if you want to clean up your code, you could change
into
First()
will throw an exception anyway, so by just changing your code you get the benefit that the assert would bring you without as much code. There are other places you can make similar changes too.But as a general rule, take nothing for granted in unit tests -- and that means lots of asserts!
这取决于您遵循的标准,但我通常会说是的,您在该测试中有太多断言。
许多人认为单个测试应该有一个断言;我认为这可能有点矫枉过正,但我确实相信对单个“块”功能进行单个单元测试是合适的;你的主张到处都是。测试太大;将其分解为几个不同的测试。
It depends on what standards you're adhering to, but I'd generally say yes, you've got far too many asserts in that test.
Many folks contend that a single test should have a single assert; I think that can be a bit of overkill, but I do certainly believe that it's appropriate to have a single unit test for a single "chunk" of functionality; you're all over the place with your asserts. The test is too big; break it up into several different tests.
一般来说,断言越多越好。单元测试中的一个常见错误是不够明确。
您的测试非常明确且可读。我特别喜欢对 null 的断言。这是一个很好的实践,因为它使解释测试失败变得非常简单。
拥有太多断言的唯一方法是,如果你多次断言完全相同的事情,但你并没有这样做。
No in general the more assertions the better. A common mistake in unit tests is not being explicit enough.
Your test is very explicit and readable. I especially like the assertions on null. It is a good practice because it makes interpreting a test failure extremely simple.
The only way you can have too many assertions is if you assert the exact same thing more than once, which you are not doing.
是的,您的代码中有太多断言!此外,每个测试方法只能有一个断言语句。使用许多断言可能会导致您正在测试不止一件事的代码味道。此外,有人可能会在您的测试中添加新的断言,而不是编写另一个断言。当第一个断言失败时,您如何理解其他断言是如何完成的?
您可能还会对这篇文章感兴趣:https://timetocode。 wordpress.com/2016/06/01/zen-of-unit-testing/
Yes, you have too many asserts in your code! Moreover, assert statement should be only one per test method. Using many asserts may be the code smell that you are testing more than one thing. Moreover, there is a chance that somebody can add new assert into your test instead of writing another one. And how can you understand how your other asserts completed when the first one failed?
You may also found interesting this post: https://timetocode.wordpress.com/2016/06/01/zen-of-unit-testing/
我认为问题是,assert()d 值是否独立变化?如果它们独立更改,则应在不同的测试中对它们进行测试,这些测试会改变与每个断言相关的条件。
但是,如果您有一个代码路径正在生成一封包含所有这些字段的电子邮件,那么在一个测试中测试所有这些内容是合适的。
现在测试有点难以阅读。您可能希望将这些断言包装在描述性帮助器方法中。在我发现相同的辅助方法在其他地方可能有用之前,我不会为此烦恼。
I think the question is, do the assert()d values change independently? If they change independently, then they should be tested in different tests that vary the conditions related to each assert.
If however you have a single codepath that is generating a an email with all those fields, then testing all those things in one test is appropriate.
Now the test is kind of hard to read though. You may want to wrap those asserts in a descriptive helper method. I wouldn't bother with that until I find the same helper method could be useful somewhere else.
您的许多断言语句表明您在单元测试中拥有多少逻辑。您必须像维护常规代码一样维护单元测试。最好把时间花在防御性编程和契约编程上,而不是编写单元测试代码。
Your many assert statements is an indicator of how much logic you have in unit tests. You are going to have to maintain your unit tests like regular code. It is better to spend time on defensive programming and programming by contract than to code unit tests.
也许您可以创建一个新的电子邮件类,在其默认构造函数中接受所有这些参数。
然后,如果用户传递无效参数,您可以抛出异常。
在单元测试
Send_sends_an_email_message
中,您可以添加仅检查相等性而不是检查 NULL 的断言。
也许您可以在一次测试中创建 2 封电子邮件,并为两个实例执行相等断言。
Maybe you can create a new Email class that accepts all those parameters in its default constructor.
And then you can throw an exception in case the user passes an invalid parameter.
And in your unit test
Send_sends_an_email_message
you can add the asserts that checks equalities only instead of checking against NULLs.
Maybe you can create 2 emails in one test and do the equality asserts for both instances.