0

We have several similar unit tests that are throwing intermittent OutOfMemoryExceptions and breaking our CI pipeline:

public void Evaluate_Node1GreaterThanNode2_ReturnsTrue_Decimal()
{
    //Arrange
    var generator = _fixture.Create<Generator<decimal>>();

    var value1 = _fixture.Create<decimal>();
    var value2 = generator.Where(x => x < value1).First();
    Node.Node1.Evaluate(Arg.Any<IPeriod>(), Arg.Any<IColleaguePeriodDataManager>()).Returns(value1);
    Node.Node2.Evaluate(Arg.Any<IPeriod>(), Arg.Any<IColleaguePeriodDataManager>()).Returns(value2);

    //Act
    var result = Node.Evaluate();

    //Assert
    Assert.IsTrue(result);
    Assert.IsTrue(Node.EvaluatedResult);
}

As you can see we're using AutoFixture's Generator to create numbers that are greater than/less than an initial value:

generator.Where(x => x < value1).First();

Obviously this approach is not working. Does anybody have a work around?

Here's the error and the stack trace:

System.OutOfMemoryException : Array dimensions exceeded supported range.
at System.Collections.Generic.HashSet`1.SetCapacity(Int32 newSize, Boolean forceNewHashCodes)
   at System.Collections.Generic.HashSet`1.AddIfNotPresent(T value)
   at Ploeh.AutoFixture.RandomNumericSequenceGenerator.GetNextRandom()
   at Ploeh.AutoFixture.RandomNumericSequenceGenerator.CreateRandom(Type request)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.Postprocessor`1.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TracingBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.TerminatingWithPathSpecimenBuilder.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context)
   at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context, T seed)
   at Ploeh.AutoFixture.SpecimenFactory.Create[T](ISpecimenContext context)
   at Ploeh.AutoFixture.Generator`1.<GetEnumerator>d__2.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
James Law
  • 6,067
  • 4
  • 36
  • 49

1 Answers1

2

It looks like the test scenario requires value2 to be greater than value1. One easy way to do that is something like this:

var x = fixture.Create<decimal>();
var y = fixture.Create<decimal>();
var value1 = Math.Min(x, y);
var value2 = Math.Max(x, y) + 0.0001m; // Add small fraction to make it strictly greater

You can refactor this to a helper method if you don't want to look at the temporary variables x and y.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736