FluentAssertions是一个很棒的库,但是当lambda中的某些代码没有按预期工作而我无法调试时,我常常感到非常沮丧。特别是当lambda复杂时。
payload.Resource.Relations.Removed.Should().NotBeNull()
.And.HaveCount(2)
.And.AllBeOfType<ResourceRelation>()
.And.OnlyContain(rel =>
rel.RelationType.MatchTo(RelationType.ArtifactLink) &&
rel.Href.AbsoluteUri.StartsWith(VsTfsSchema.GitPullRequestId));
在这种情况下,我想在OnlyContain(...)
lambda内部设置一个断点并进行调试。但这是不可能的 - 断点总是在整个声明中设置。我想原因是FluentAssertions中的lambda是表达式。
有什么方法可以实现这个目标吗?
编辑:将lambda提取为局部变量没有帮助。行为是一样的。
System.Linq.Expressions.Expression<Func<ResourceRelation, bool>> predicate = rel =>
rel.RelationType.MatchTo(RelationType.ArtifactLink) && rel.Href.AbsoluteUri.StartsWith(VsTfsSchema.GitPullRequestId);
payload.Resource.Relations.Removed.Should().NotBeNull()
.And.HaveCount(2)
.And.AllBeOfType<ResourceRelation>()
.And.OnlyContain(predicate);
Edit2:这是一个非常简单且可验证的例子。您不能将断点放入num == 1
,也不能将其作为本地函数提取,也不能在监视时显示。
[Fact]
public void SimpleLambdaTest()
{
int[] nums = Enumerable.Range(1, 10).ToArray();
nums.Should().OnlyContain(num => num == 1);
}
您可以将表达式主体提取到静态函数中,您可以在其中设置断点。
请注意,EqualsOne
不能是本地函数,不能作为方法组传递。
[Fact]
public void SimpleLambdaTest()
{
int[] nums = Enumerable.Range(1, 10).ToArray();
nums.Should().OnlyContain(num => EqualsOne(num));
}
private static bool EqualsOne(int num)
{
// You can put a break point here
return num == 1;
}
虽然这与FluentAssertions无关,但我经常与Jetbrains Rider这样做。当你试图设置一个断点时,它会问你想要它的位置;在整个生产线上,在一个单独的lambda等上我已经有近两年的Visual Studio调试了,所以我不知道它是否可以处理。
即使如此,如果你在断线上按F11,调试应该带你到lambda表达式。如果没有,您仍然可以使用Add Watch
或Quick Watch
工具(选择lambda表达式 - >右键单击并选择Quick Watch)