Mathias F
Mathias F

Reputation: 15921

Mock a call to a Repository that uses Ardalis Specification

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?

Upvotes: 0

Views: 45

Answers (1)

Sebastian N
Sebastian N

Reputation: 31

Have you tried putting "new ProductByIdSpec(42)" into a variable and using it in both instances?

var spec = new ProductByIdSpec(42);
_productRepository.SingleOrDefaultAsync(Arg.Is(spec)
         .Returns(product);
_productRepository.SingleOrDefaultAsync(spec);

Doing "new" two times creates two different instances of the spec. I think this can block the comparison.

Upvotes: 0

Related Questions