The 适用于 .NET 的 Shouldly 断言库 http://shouldly.readthedocs.io/en/latest/以某种方式知道断言方法被调用的表达式,因此它能够将其显示到消息中。我试图找出它是如何工作的,但迷失在源代码中。我怀疑它会查看编译后的代码,但我真的很想看看这是如何发生的。从文档中
map.IndexOfValue("boo").ShouldBe(2); // -> map.IndexOfValue("boo") should be 2 but was 1
不知何故应该知道表达式map.IndexOfValue(“boo”)并能够在测试失败消息中显示它。有谁知道这是怎么发生的?
看看代码,这非常聪明。
魔法正在发生ActualCodeTextGetter
班级。首先,它使用 StackTrace 检索源代码文件的行:
StackTrace stackTrace = trace ?? new StackTrace(true);
// Cut for brevity
StackFrame stackFrame = frame;
this.ShouldlyFrameIndex = index - 1;
string fileName = stackFrame.GetFileName();
this._determinedOriginatingFrame = fileName != null && File.Exists(fileName);
this._shouldMethod = this.ShouldlyFrame.GetMethod().Name;
this.FileName = fileName;
this.LineNumber = stackFrame.GetFileLineNumber() - 1;
一旦它有了源代码文件的名称以及语句的行和偏移量,就只需直接读取文件即可:
private string GetCodePart()
{
string str = "Shouldly uses your source code to generate its great error messages, build your test project with full debug information to get better error messages\nThe provided expression";
if (this._determinedOriginatingFrame)
{
string codeLines = string.Join("\n", ((IEnumerable<string>) File.ReadAllLines(this.FileName)).Skip<string>(this.LineNumber).ToArray<string>());
int indexOfMethod = codeLines.IndexOf(this._shouldMethod);
if (indexOfMethod > 0)
str = codeLines.Substring(0, indexOfMethod - 1).Trim();
str = !str.EndsWith("Should") ? str.RemoveVariableAssignment().RemoveBlock() : this.GetCodePartFromParameter(indexOfMethod, codeLines, str);
}
return str;
}
有更多的逻辑可以精确地隔离该语句,但简而言之,技巧是:
- 使用 StackTrace 检索源代码的位置和语句行
- 解析源代码以检索准确的语句
当然,只有当您在用于编译代码的同一台机器上运行它时,它才能工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)