在我正在测试的应用程序中,我想确保在某些输入中调用记录器。某些方法具有不同的可能记录器消息(例如“值格式错误”,“值超出范围”)。因此,我想确保使用正确的消息调用记录器。
它们所在的记录器字符串位于RESX中,并且可能在将来进行本地化。此外,措辞可能会改变。因此,简单地与硬编码字符串进行比较可能会导致文本更改时中断相关测试。由于它们是可本地化的,这意味着我必须强制单元测试在某种文化下执行,还是有更好的方法?
使这一点复杂化,RESX字符串实际上并不像上面那么简单,而是形式为"Line {0}: Value '{1}' at column {2} is malformed."
,然后将其用作string.Format()的输入以生成"Line 12: Value '12a.45' at column 45 is malformed."
。这是记录器实际获得的字符串。我应该将此字符串硬编码到单元测试中吗?
编辑:
我将尝试用更简单的方法解释一下,用一种强烈简化的方法来表明我的意思:
public void ConvertSomething(object value)
{
if (/* Check if valid value */)
{
var convertedValue = /* Some conversion */ ;
if (/* Check is in range */)
{
// Do something
}
else
{
Logger.Log(string.Format(Resources.OutOfRange, LineNumber, convertedValue));
}
}
else
{
Logger.Log(string.Format(Resources.InvalidValue, LineNumber, value, ColumnNumber));
}
}
如何测试使用正确的消息调用记录器?我不能简单地检查是否有任何对记录器的调用。如果我给它一个有效但超出范围的值,但是有效性检查有一个错误,它将调用记录器,但是消息“无效值”,它应该实际上是“超出范围”。< / p>
我可以模拟记录器,所以我可以看到它被调用了,参数是什么。但我应该断言什么呢?
答案 0 :(得分:3)
如果机器上存在文化,您可以在代码中更改当前的线程文化。如果它不存在,则需要安装/创建它。
至于比较应用程序中使用的字符串(可能会改变),我建议不要将其作为测试的目标。
相反,可能在每个静态资源中都有一个健全性测试字符串,并对其进行测试。如果随着文化的变化而变化,那么您已经加载了正确的资源,并且可以安全地假设其余内容也是正确的。
NUnit支持改变测试工具的文化:
http://www.nunit.org/index.php?p=culture&r=2.4.8
更新:我看到问题是测试无法查看记录器?我建议你可以模拟一个记录器而不是知道它正在测试并包含它自己的断言,或者放弃测试记录器本身并测试当前加载文化组件的卫星组件。如果记录器只使用资源文件,那么.NET运行时将处理正确文件的加载或默认为基本文化文件。
然后,您可以进行单独的测试以显示记录器记录,而不必担心其记录的内容,因为另一个测试中包含该记录。
更新2:我想我知道你要做的是什么。是否可以让记录器接受字符串格式和params object[] args
以便在插入特定值之前访问字符串?
或者,是否可以将字符串设置为静态或者是否可以改变每次测试运行?如果测试本身负责首先播种值,则测试中的值是硬编码的。此外,对于文化,我将分别针对选择不同消息的不同代码路径引入的更改来解决这些更改。
更新3:抱歉,我看不到树木。测试本身可以从代码使用的resx文件构建预期的字符串 - 并且只需插入硬编码值。这取决于每次运行的测试输出没有差异。
如果resx发生了变化,那么只要插入到格式化字符串中的值的数量没有变化,就不需要修改代码或测试。
答案 1 :(得分:0)
您创建了一个假记录器,并监视您的代码在需要时调用它。