3

Below mentioned is the test function that checks if details exist for the particular transactionId.

        [Fact]
        public async Task GetAllBlobDetails_Test()
        {
           _serviceScopeFactory.Setup(x => x.CreateScope().ServiceProvider.GetRequiredService<MriDbContext>()).Returns(_context);
           BlobStatusEntity blobStatusEntity =  await _bspRepository.GetBlobDetails("123");
           Assert.NotNull(blobStatusEntity)
        }

where _serviceScopeFactory is

Mock<IServiceScopeFactory> _serviceScopeFactory = new Mock<IServiceScopeFactory>();
(Microsoft.Extensions.DependencyInjection)

In the above function it calls _bspRepository.GetBlobDetails for particular transactionId ("123")

So here is the definition for GetBlobDetails

 public async Task<BlobStatusEntity> GetBlobDetails(string transactionId)
        {

                if (String.IsNullOrEmpty(transactionId))
                {
                    throw new ArgumentNullException(nameof(transactionId));
                }

                MriDbContext mriDbcontext = _scopeFactory.CreateScope().ServiceProvider.GetRequiredService<MriDbContext>();

                return await mriDbContext.BlobStatus.FirstOrDefaultAsync(ele => ele.TransactionId == transactionId);
        }

where _scopeFactory is IServiceScopeFactory _scopeFactory which is injected from the constructor.

When I am running the above test function GetAllBlobDetails_Test, I am getting the following error like this.

Message: 
    System.NotSupportedException : Unsupported expression: ... => ....GetRequiredService<MriDbContext>()
    Extension methods (here: ServiceProviderServiceExtensions.GetRequiredService) may not be used in setup / verification expressions.

I am new to moq and xunit.

Please help me to resolve this issue.

Thanks in advance

1
  • In test code, I am using an in-memory database and I created my context which is linked to in-memory database instead of the using real database. Commented Jul 14, 2020 at 15:41

2 Answers 2

3

So the root cause here is that you can't mock an extension method in Moq

You're doing this here:

 _serviceScopeFactory.Setup(x => x.CreateScope().ServiceProvider.GetRequiredService<MriDbContext>()).Returns(_context);

GetRequiredService<T> is an extension method that extends IServiceProvider which you can see here

Depending on what the specific case you're trying to test is (are you testing the context creation, or the actual write to the DB?), you should be able to re-write your test to avoid mocking the extension method and mocking the public instance methods being used instead. You could even mock the actual instance method on IServiceProvider if you really wanted to keep the existing structure.

Further discussion of this topic exists here. That question uses MSTest rather than XUnit, but your issue here is specific to Moq.

Sign up to request clarification or add additional context in comments.

Comments

2

Here is the initialization part

  private BspRepository _bspRepository;
        private Mock<IServiceScopeFactory> _serviceScopeFactory;
        private Mock<ILogger<BspRepository>> _logger;
        private Mock<IMapper> _mapper;
        private DbContextOptions<MriDbContext> _options;
        private MriDbContext _context;
        private Mock<IServiceProvider> _serviceProvider;
        private Mock<IServiceScope> _serviceScope;
        public BSPRepositoryTests()
        {
            _serviceScopeFactory = new Mock<IServiceScopeFactory>();
            _logger = new Mock<ILogger<BspRepository>>();
            _mapper = new Mock<IMapper>();
            _serviceProvider = new Mock<IServiceProvider>();
            _serviceScope = new Mock<IServiceScope>();
            _options = SetupDBContext();
            _context = new MriDbContext(_options);
            _bspRepository = new BspRepository(_serviceScopeFactory.Object, _logger.Object, _mapper.Object);
            SetupData();
            SetupServices();

        }

I resolved my error by mocking objects in this way

 private void SetupServices()
        {
            _serviceProvider.Setup(x => x.GetService(typeof(MriDbContext))).Returns(_context);
            _serviceScope.Setup(x => x.ServiceProvider).Returns(_serviceProvider.Object);
            _serviceScopeFactory.Setup(x => x.CreateScope())
                .Returns(_serviceScope.Object);
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.