Search code examples
.netunit-testingdependency-injectionmoqunit-of-work

Unit of Work has null repository property in Unit Test


I cannot run a unit test from the BLL/Service layer. The test mocks the Unit of Work because its a unit test for a service method. Thus, the uow mock has a null repository property which fails the unit test.

Unit Test Initialize

[TestInitialize]
public void TestInitialize()
{
  ServiceCollection.AddSingleton<IUploadFilesService, UploadFilesService>();

  // Mocks
  var uploadFilesRepositoryMock = new Mock<UploadFilesRepository>();
  uowMock = new Mock<IUnitOfWork>();
  uowMock.SetupGet(el => el.UploadFilesRepository).Returns(uploadFilesRepositoryMock.Object); 
  // errors here because interface has no setter

  // Register services
  ServiceCollection.AddSingleton(uowMock.Object);

  BuildServiceProvider();
  service = (UploadFilesService)ServiceProvider.GetService<IUploadFilesService>();
}

The interface has only getters for safety and probably should remain that way.

public interface IUnitOfWork : IDisposable
{
    IUploadFilesRepository UploadFilesRepository { get; }
    int Complete();
}

UploadFilesService

void SetStatus() 
{
    unitOfWork.UploadFilesRepository.SetStatus(files, status);
}

Error: UploadFilesRepository is null.

I try to instantiate the repository in multiple ways:

  1. Mock concrete class and not interface.
// Mocks
var uploadFilesRepositoryMock = new Mock<UploadFilesRepositoryMock>();
uowMock = new Mock<UnitOfWork>(null, uploadFilesRepositoryMock );

// Register services
ServiceCollection.AddSingleton(uowMock.Object);

Error on ServiceCollection.AddSingleton.

Message=Can not instantiate proxy of class: Repositories.UnitOfWork.
Could not find a constructor that would match given arguments:...
  1. Pass constructor arguments to interface mock.
    uowMock = new Mock<IUnitOfWork>(null, uploadFilesRepositoryMock);

Error:

Constructor arguments cannot be passed for interface mocks.
  1. Use uow.SetupGet().
    Error:
System.ArgumentException
  HResult=0x80070057
  Message=Can not instantiate proxy of class: 
Could not find a parameterless constructor. (Parameter 'constructorArguments')

I searched other questions regarding these unit test errors, but they don't tackle the case in which I use dependecy injection AddSingleton method. Which for consistency I use in all my tests in [TestInitialize] for a clearer code format.


Solution

  • It seems I can setup the UoW mock and the getter method by using only Setup and it works this way.

    var uploadFilesQueueRepositoryMock = new Mock<IUploadFilesQueueRepository>();
    uowMock = new Mock<IUnitOfWork>();
    uowMock.Setup(m => m.UploadFilesQueueRepository).Returns(uploadFilesQueueRepositoryMock.Object);
    

    I tried SetupGet(), mock concrete class, AddSingleton, but the solution was only using the method Setup().