Dai*_*Dai 4 c# unit-testing assert xunit shouldly
我在我的 xUnit 测试中使用了优秀的Shouldly库,我发现自己在不同的测试中使用了断言的集合序列,所以我将它们组合成新的断言扩展方法 - 但是当我这样做时,我丢失了Shouldly上下文断言消息。
这是我的旧代码,它Shouldly用于在Shouldly断言错误中包含源级信息和调用站点上下文:
[Fact]
public void Dict_should_contain_valid_Foobar_Bar_entry()
{
IDictionary<String,Bar> dict = ...
dict.TryGetValue( "Foobar", out Bar bar ).ShouldBeTrue();
bar.ShouldNotBeNull();
bar.ChildList.Count.ShouldBe( expected: 3 );
bar.Message.ShouldBeNull();
}
[Fact]
public void Dict_should_contain_valid_Barbaz_Bar_entry()
{
IDictionary<String,Bar> dict = ...
dict.TryGetValue( "Barbaz", out Bar bar ).ShouldBeTrue();
bar.ShouldNotBeNull();
bar.ChildList.Count.ShouldBe( expected: 3 );
bar.Message.ShouldBeNull();
}
Run Code Online (Sandbox Code Playgroud)
我在同一个项目中将它转换为这个新的扩展方法:
public static void ShouldBeValidBar( this IDictionary<String,Bar> dict, String barName )
{
dict.ShouldNotBeNull();
dict.TryGetValue( barName, out Bar bar ).ShouldBeTrue();
bar.ShouldNotBeNull();
bar.ChildList.Count.ShouldBe( expected: 3 );
bar.Message.ShouldBeNull();
}
Run Code Online (Sandbox Code Playgroud)
所以我的测试变成了这样:
[Fact]
public void Dict_should_contain_valid_Foobar_Bar_entry()
{
IDictionary<String,Bar> dict = ...
dict.ShouldBeValidBar( "Foobar" );
}
[Fact]
public void Dict_should_contain_valid_Barbaz_Bar_entry()
{
IDictionary<String,Bar> dict = ...
dict.ShouldBeValidBar( "Barbaz" );
}
Run Code Online (Sandbox Code Playgroud)
...但现在我的 Shouldly 断言消息不包含来自 的任何上下文信息Dict_should_contain_valid_Foobar_Bar_entry,而是仅包含来自 的上下文ShouldBeValidBar。
我如何指示Shouldly忽略ShouldBeValidBar其父调用站点的上下文并使用其父调用站点?
将[ShouldlyMethods]属性添加到您的自定义断言扩展方法类(不是单个扩展方法):
[ShouldlyMethods] // <-- This, right here!
public static class MyShouldlyAssertions
{
public static void ShouldBeValidBar( this IDictionary<String,Bar> dict, String barName )
{
[...]
}
}
Run Code Online (Sandbox Code Playgroud)
经过一些谷歌搜索,并阅读了有关如何Shouldly工作的文章- 并阅读了 Shouldly's secret-sauce: 的来源SourceCodeTextGetter之后,我看到它确定了堆栈跟踪中的哪些条目可以通过[ShouldlyMethods]Shouldly.ShouldlyMethodsAttribute方法包含的属性( )的存在而被忽略在堆栈跟踪的每一帧中键入:
void ParseStackTrace(StackTrace trace)
{
[...]
while (ShouldlyFrame == null || currentFrame.GetMethod().IsShouldlyMethod())
{
if (currentFrame.GetMethod().IsShouldlyMethod())
ShouldlyFrame = currentFrame;
[...]
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
internal static bool IsShouldlyMethod(this MethodBase method)
{
if (method.DeclaringType == null)
return false;
return
method
.DeclaringType
.GetCustomAttributes( typeof(ShouldlyMethodsAttribute), true )
.Any()
||
(
method.DeclaringType.DeclaringType != null
&&
method
.DeclaringType
.DeclaringType
.GetCustomAttributes( typeof(ShouldlyMethodsAttribute), true )
.Any()
);
}
Run Code Online (Sandbox Code Playgroud)
所以这只是将[ShouldlyMethods]属性添加到我的扩展方法的容器类的问题:
[ShouldlyMethods]
public static class ShouldlyAssertionExtensions
{
public static void ShouldBeValidBar( this IDictionary<String,Bar> dict, String barName )
{
dict.ShouldNotBeNull();
dict.TryGetValue( barName, out Bar bar ).ShouldBeTrue();
bar.ShouldNotBeNull();
bar.ChildList.Count.ShouldBe( expected: 3 );
bar.Message.ShouldBeNull();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的断言错误具有ShouldBeValidBar. 欢呼!
| 归档时间: |
|
| 查看次数: |
335 次 |
| 最近记录: |