Shouldly断言库如何知道断言所应用于的表达式? [英] How does the Shouldly assertion library know the expression the assertion was applied to?
问题描述
针对.NET的断言库应该以某种方式知道调用断言方法的表达式,因此它能够将其显示在消息中.我试图找出它是如何工作的,但在源代码中迷路了.我怀疑它会查看已编译的代码,但我真的很想看看这是如何发生的.从文档中
The Shouldly assertion library for .NET somehow knows what expression the assertion method was called on so it is able to display it into the message. I tried to find out how it works but got lost in the source code. I suspect it looks into the compiled code but I would really like to see how this happens. From the documentation
map.IndexOfValue("boo").ShouldBe(2); // -> map.IndexOfValue("boo") should be 2 but was 1
以某种方式应该知道表达式map.IndexOfValue("boo")并能够在测试失败消息中显示它.有谁知道这是怎么发生的?
Somehow Shouldly knows the expression map.IndexOfValue("boo") and was able to display it in the test failure message. Does anyone know how this happens?
推荐答案
看看代码,这很聪明.
魔术发生在 ActualCodeTextGetter
类中.首先,它使用StackTrace检索源代码文件的行:
The magic is happening in the ActualCodeTextGetter
class. First, it retrieves the line of the source code file by using the 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;
一旦有了源代码文件的名称,以及语句的行和偏移量,就可以直接读取文件:
Once it has the name of the source code file, along with the line and offset of the statement, it's just a matter of reading directly the file:
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;
}
还有很多逻辑可以精确地隔离该语句,但总而言之,诀窍是:
There's a lot more logic going on to isolate precisely the statement, but in short the trick is:
- 使用StackTrace检索源代码的位置和语句的行
- 解析源代码以获取确切的语句
当然,只有在用于编译代码的同一台计算机上运行它时,它才可以工作.
Of course, it can work only if you're running it on the same machine you used to compile the code.
这篇关于Shouldly断言库如何知道断言所应用于的表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!