-
Notifications
You must be signed in to change notification settings - Fork 731
Closed
Description
Description
The "parameterless" variant of ContainSingle() (without a predicate) evaluates IEnumerables twice. This means any side-effects in the enumerable chain are executed twice which might lead to unexpected behavior.
Complete minimal example reproducing the issue
https://dotnetfiddle.net/SFGRnc
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
var d = new Dictionary<int, int>();
var xs = new[] { 1 }
.Select(x => {
d.Add(x, x); // crashes if executed twice
return x;
});
xs.Should().ContainSingle(); // crashes
//xs.Should().ContainSingle(_ => true); // does not crashExpected behavior:
xs.Should().ContainSingle(); should not crash.
Actual behavior:
xs.Should().ContainSingle(); crashes.
Versions
- FluentAssertions 6.2.0
- .NET 6.0
Additional Information
The problem is that ContainSingle() uses Count() here and also SingleOrDefault() here without materializing the enumerable first.
The variant taking a predicate does materialize the enumerable first here.