1

FluentAssertions is a great library but often I am very frustrated when some code in lambda is not working as expected and I cannot debug it. Especially when lambda is complicated.

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));

In this case, I would like to set a breakpoint into inside OnlyContain(...) lambda and debug it. But this is not possible - breakpoint is set always at the whole statement. I suppose that the reason is that lambdas in FluentAssertions are expressions.

Is there any way how to achieve this?

Edit: Extracting lambda as local variable does not help. Behavior is the same.

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: Here is really simple and verifiable example. You cannot put a breakpoint into num == 1, nor extract it as local function, nor display it at watch.

[Fact]
public void SimpleLambdaTest()
{
    int[] nums = Enumerable.Range(1, 10).ToArray();
    nums.Should().OnlyContain(num => num == 1);
}
Karel Kral
  • 5,297
  • 6
  • 40
  • 50

3 Answers3

3

You can extract the expression body into a static function, in which you can set a breakpoint.

Note that EqualsOne cannot be a local function and cannot be passed as a method group.

[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;
}
Jonas Nyrup
  • 2,376
  • 18
  • 25
1

Although this has nothing to do with FluentAssertions, I do this quite often with Jetbrains Rider. When you try to set a breakpoint, it'll ask you where you want to have it; on the entire line, on an individual lambda, etc. I haven't debugged with Visual Studio for almost two years now, so I don't know if it can handle.

Dennis Doomen
  • 8,368
  • 1
  • 32
  • 44
0

Even if so, if you hit F11 on the breaked line debug should take you to the lambda expression. If not, you can still use Add Watch or Quick Watch facility (Select the lambda expression -> right click and select Quick Watch)

Rahul
  • 76,197
  • 13
  • 71
  • 125
  • No, this does not work also. I can display predicate in a debugger, but it is expression also. Also, what value could be displayed, if the breakpoint is not inside the lambda? This is what I see in Watch: `+ predicate {rel => (rel.RelationType.MatchTo("ArtifactLink") AndAlso rel.Href.AbsoluteUri.StartsWith("vstfs:///Git/PullRequestId"))} System.Linq.Expressions.Expression> {System.Linq.Expressions.Expression1>}` – Karel Kral Mar 06 '19 at 12:04