C# 错误消息的单元测试内容?
我有一个类,它引发一个带有错误消息的事件 在我的一些测试中,我订阅事件并断言错误消息不是空的C# 错误消息的单元测试内容?,c#,.net,unit-testing,C#,.net,Unit Testing,我有一个类,它引发一个带有错误消息的事件 在我的一些测试中,我订阅事件并断言错误消息不是空的 [Test] public MyMethod_DoBad_ErrorMessageNotEmpty() { var logic = new MyClass(); string ErrorMessage = String.Empty; logic.DisplayError += delegate(string s) { ErrorMessage = s
[Test]
public MyMethod_DoBad_ErrorMessageNotEmpty()
{
var logic = new MyClass();
string ErrorMessage = String.Empty;
logic.DisplayError += delegate(string s)
{
ErrorMessage = s;
};
logic.DoItBadly();
Assert.IsFalse(String.IsNullOrWhiteSpace(ErrorMessage));
}
//MyClass
public void DoItBadly()
{
//do something naughty but not final
DisplayError("Naughty");
//some other problem arises
if (1==1)
DisplayError("Something else naughty");
}
然而,我开始发现在边缘案例测试中,我的新测试应该失败,因为它在到达我想要的地方之前在代码中引发了一个错误事件
因此,我应该断言错误消息包含指定的字符串吗
然而,我开始发现在边缘案例测试中,我的新测试应该失败,因为它在到达我想要的地方之前在代码中引发了一个错误事件
这表明您要么在测试之间重用现有对象,要么您的测试做得太多。如果您无法在要测试的实际操作之前完成工作,您可以将测试编写为:
// Construct objects
// Do setup work
// Check that there's no error message yet
// Do work you expect to fail
// Check that there *is* an error message
当然,您可以检查确切的错误消息,但这可能会非常耗时。如果您使用的是合理的临时错误报告(不必担心i18n等),那么我个人只需检查是否存在错误消息。理想情况下,您需要隔离并抽象DoItBadly()中的区域,这些区域会用错误消息污染您的错误文本,这样您就可以毫无问题地测试该方法的其余部分 然而,考虑到说起来容易做起来难,下一个最好的办法是在满足某个条件(或者有一个不会填充ErrorMessage的错误消息白名单)的情况下,只使用s填充ErrorMessage。因此,如果您仅在错误不是您认为“可接受”的错误时设置ErrorMessage,那么您的测试应该通过,并且您自己的要求应该得到满足
尽管更好的做法是坚持积极的结果,而不是让你的成功案例没有消极的结果。我认为你应该在不同的测试中测试这两种情况:
[Test]
public ShouldRaiseNaughtyErrorWhenDoBadly()
{
var logic = new MyClass();
string errorMessage = String.Empty;
logic.DisplayError += delegate(string s) {errorMessage = s; };
logic.DoItBadly();
Assert.That(errorMessage, Is.EqualTo("Naughty"));
}
[Test]
public ShouldRaiseElseNaughtyErrorWhenDoBadlyWithOtherProblem()
{
var logic = new MyClass();
string errorMessage = String.Empty;
logic.DisplayError += delegate(string s) {errorMessage = s; };
// do something for other problem condition
logic.DoItBadly();
Assert.That(errorMessage, Is.EqualTo("Something else naughty"));
}
或者,如果需要检查引发的两个错误:
[Test]
public ShouldRaiseBothErrors()
{
var logic = new MyClass();
List<string> errorMessages = new List<string>();
logic.DisplayError += delegate(string s) {errorMessages.Add(s); };
// do something for other problem condition
logic.DoItBadly();
Assert.That(errorMessages.Count, Is.EqualTo(2));
Assert.That(errorMessages[0], Is.EqualTo("Naughty"));
Assert.That(errorMessages[1], Is.EqualTo("Something else naughty"));
}
[测试]
公众应该提出反对意见
{
var逻辑=新的MyClass();
List errorMessages=新列表();
logic.DisplayError+=委托(字符串s){errorMessages.Add(s);};
//针对其他问题情况采取措施
logic.DoItBadly();
Assert.That(errorMessages.Count,Is.EqualTo(2));
Assert.That(errorMessages[0],是.EqualTo(“顽皮”);
Assert.That(errorMessages[1],是.EqualTo(“其他顽皮的东西”);
}
更新:
考虑到通知基于事件的性质,您可以捕获所有通知,然后搜索一些具体错误:
[Test]
public ShouldRaiseNaughtyErrorWhenDoBadly()
{
var logic = new MyClass();
List<string> errorMessages = new List<string>();
logic.DisplayError += delegate(string s) { errorMessages.Add(s); };
logic.DoItBadly();
Assert.That(errorMessages.Contains("Naughty"));
}
[测试]
当发生严重()
{
var逻辑=新的MyClass();
List errorMessages=新列表();
logic.DisplayError+=委托(字符串s){errorMessages.Add(s);};
logic.DoItBadly();
Assert.That(errorMessages.Contains(“顽皮”));
}
如果您能为测试提供一些代码,那就太好了。您的测试是独立的,还是共享一些数据?问题是我的ErrorMessage变量是由DoItBadly中的错误事件填充的,该事件在到达我希望它测试的代码行之前发生。这不是重复使用任何东西。只是第10行引发了一个错误事件,但我想测试第20行也引发了错误事件event@Jon:对,就像我说的,检查它在第20行之前是否为空。如果您预期之前会出现错误,则需要在调用真正要测试的方法之前清除错误。这是一个正在测试的方法,这就是问题。如果您要测试这两个功能,可能需要重构。@Jon:就调用代码而言,DoItBadly
中出现了一些错误。您可以通过在事件处理程序中添加列表
来检查预期的错误数,如果这样有帮助的话。。。(或者,如果不需要查看消息本身,只需增加一个整数。)