I am trying to mock a repository that inherits from the BaseRepository class in the Ardalis.Specification.EntityFrameworkCore library. This base class exposes the ListAsync method which takes in a subclass of the Specification class.
This is one of those specifications I have built:
public sealed class SomeSpecification: Specification<SomeEntity>
{
public SomeSpecification(Guid someSubEntityID)
{
Query
.Include(p => p.SomeSubEntity)
.Where(p => p.SomeSubEntity.Id == someSubEntityID)
.Include(p => p.SomeOtherSubEntity)
.OrderBy(p => p.SomeProperty);
}
}
When writing unit tests, I am trying to configure a mock for my ISomeEntityRepository for this specific method using this specification class. What I want is to be able to return a specific collection when this method is passed any SomeSpecification object that was built using a SPECIFIC guid. As you see, the id that is passed to this constructor is not store anywhere in the class as a property or field when constructing it.
What I can do is something like this where the method just returns a specific collection I'm storing in an EntityConstants class when any SomeSpecification is passed:
_pfRepoMock.ListAsync(
Arg.Any<SomeSpecification>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(EntityConstants.SomeEntityCollection()));
This works fine but I'm not able to return 2 different collections depending on what guid was passed to the SomeSpecification constructor. In my ideal world, what I'd like to be able to do, is something like this:
_pfRepoMock.ListAsync(
Arg.Any<SomeSpecification>().ConstructedWith(EntityConstants.SomeID), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(EntityConstants.SomeEntityCollection()));
_pfRepoMock.ListAsync(
Arg.Any<SomeSpecification>().ConstructedWith(EntityConstants.SomeOtherID), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(EntityConstants.SomeDifferentEntityCollection()));
I know there is an NSubstitute.Equivalency library that adds an ArgEx class but I can't see how it can accomplish what I want.
How can I achieve this?