I have a generic Repository (RepositoryBase) that gets queried using a specification
Specification
public sealed class ProductByIdSpec : SingleResultSpecification<Product>
{
public ProductByIdSpec (int id)
{
Query
.Where(p => p.Id == id);
}
}
I then used NSubstitute to mock the repository in unittests.
_productRepository = Substitute.For<IReadRepositoryBase<Product>>();
I can use the generic matcher to return a Product
_assetRepository.SingleOrDefaultAsync( Arg.Any<ProductByIdSpec>()) .Returns(product);
The Product is then retrieved by calling
_productRepository.SingleOrDefaultAsync(new ProductByIdSpec(42));
I dont find a way to set up a matcher that takes into account the id
I tried
_productRepository.SingleOrDefaultAsync( Arg.Is(new ProductByIdSpec(42))
.Returns(product);
But this does return null with
_productRepository.SingleOrDefaultAsync(new ProductByIdSpec(42));
I get it that at some point there needs to be a comparison of two instances of new ProductByIdSpec(42) which does not work for me.
I tried top use a lambda but dont find a way for getting the "42" in the object new ProductByIdSpec(42)
_productRepository.SingleOrDefaultAsync(
Arg.Is<ProductByIdSpec>(x => x.SearchCriterias ??????))
.Returns(product);
Is there a way to use Ardalis Specification together with NSubstitute for the case I showed?
You need to save the id as a public property in the spec:
public sealed class ProductByIdSpec : SingleResultSpecification<Product>
{
public int Id { get; }
public ProductByIdSpec(int id)
{
Id = id;
Query.Where(p => p.Id == id);
}
}
Then in the test just do:
_productRepository.SingleOrDefaultAsync(
Arg.Is<ProductByIdSpec>(x => x.Id == 42)
).Returns(product);
Now it works.