简体   繁体   中英

Constructor parameters did not have matching fixture data, when trying to test a service using xUnit. What does this mean and where is my issue?

I'm trying to write some unit tests for my service(s).

I'm just trying to get the hang of a simple one, just testing the GetAsync method of my service, using xUnit and Moq.

Here's my code:

namespace HRB_Server.Tests.Services
{
    public class PhaseServiceTest
    {
        private readonly Mock<IRepository<Phase>> _repository;
        private readonly Mock<IMapper> _mapper;
        private readonly Mock<HrbContext> _context;

        public PhaseServiceTest()
        {
            _repository = new Mock<IRepository<Phase>>();
            _mapper = new Mock<IMapper>();
            _context = new Mock<HrbContext>();
        }

        [Fact]
        public void GetPhase_ActivePhaseObject_PhaseShouldExist()
        {
            // Arrange
            var newGuid = Guid.NewGuid();
            var phase = GetSamplePhase(newGuid);

            _repository.Setup(x => x.GetAsync(It.IsAny<Guid>()))
                .Returns(GetSamplePhase(newGuid));

            var phaseService = new PhaseService(_repository.Object, _mapper.Object, _context.Object);

            // Act
            var result = phaseService.GetAsync(newGuid);

            // Assert (expected, actual)
            Assert.Equal(phase.Id, result.Id);
    }
}

This code produces the following error:

The following constructor parameters did not have matching fixture data: IMapper mapper, HrbContext context

My "real" service requires 3 objects, the IRepository, the automapper, and the context.

What am I doing wrong here?

EDIT:

Here's my IRepository class:

public interface IRepository<T> : IDisposable
{
    Task<T> GetAsync(Expression<Func<T, bool>> predicate);
    Task<T> GetAsync(Guid id);
} 

Here's my Context class:

public class HrbContext : IdentityDbContext<ApplicationUser>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    // DBsets are here...

     public HrbContext(DbContextOptions<HrbContext> options, IHttpContextAccessor httpContextAccessor)
        : base(options)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         ... 
    }
}

The Mapper class is really the "AutoMapper" one, from the Nuget Package.

Your error is because your HrbContext has a constructor with 2 parameters, which you haven't specified when mocking.

public HrbContext(DbContextOptions<HrbContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
{
    _httpContextAccessor = httpContextAccessor;
}

Moq needs a public default constructor when mocking, or you need to create the mock object with the constructor parameters.

Since you are already mocking the return value of _repository.GetAsync , you don't really need any real implementation inside the DbContext as it won't even be called.

In this case, as we don't want to mock or need the real implementation of DbContextOptions<HrbContext> or IHttpContextAccessor , pass them as null .

_context = new Mock<HrbContext>(null, null);

If you do need them (in other tests etc.), either mock them too or pass real instances through:

var options = new DbContextOptions<HrbContext>(...);
var httpContextAccessor = new HttpContextAccessor(...);
_context = new Mock<HrbContext>(options, httpContextAccessor);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM