DeepEqual
DeepEqual copied to clipboard
StackOverflow exception on object graphs with cycles
In version 0.12.0.0 installed from NuGet, I get a StackOverflowException when an object graph contains cycles.
Sample below:
public class A
{
public List<B> Bees { get; set; }
}
public class B
{
public A A { get; set; }
}
public class C
{
public D D { get; set; }
}
public class D
{
public C C { get; set; }
}
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B { A = a };
a.Bees = new List<B> { b };
var a1 = new A();
var b1 = new B { A = a1 };
a1.Bees = new List<B> { b1 };
a1.ShouldDeepEqual(a); //stack overflow exception
b1.ShouldDeepEqual(b); //stack overflow exception
var c = new C();
var d = new D { C = c };
c.D = d;
var c1 = new C();
var d1 = new D { C = c1 };
c1.D = d1;
c1.ShouldDeepEqual(c); //stack overflow exception
d1.ShouldDeepEqual(d); //stack overflow exception
}
}
This is still occurring in the latest version (as of today v1.4) from nuget.
Looking forward to have it fixed :)
Is there a workaround to it? Something as simple as a LimitRecursionDepth method would do.
This is a common issue with navigation properties (1 - n) in entity framework! If you use this on a entity with said relationship in a unit test, the test spins for a while and then gets aborted!
Currently I have to ignore those properties and then loop through the list of childs and compare them separately...
Please look into this!
I have worked around it using custom comparisons like this one: https://github.com/asgerhallas/ShouldBeLike/blob/master/ShouldBeLike/CyclesComparison.cs
Note: Above comparison is not thread safe and should not be reused between comparisons. Make a new instance for every call to ShouldDeepEqual(). I have also made a thread safe version, but it was quite a bit more complex :)
This also happens when using JsonObject from System.Text.Json. Even if you have 2 different objects.
i got the same problems
Note: Above comparison is not thread safe and should not be reused between comparisons. Make a new instance for every call to ShouldDeepEqual(). I have also made a thread safe version, but it was quite a bit more complex :)
if there any API like IsDeepEqual direct return true/false in you repository ShouldBeLike ?
@jamesfoster any update for this issue ?
Added ability to ignore circular references in v5.0.0
actual
.WithDeepEqual(expected)
.IgnoreCircularReferences()
.Assert()