简体   繁体   中英

Mocking an interface which is { get; } only (Moq)

I have an IUnitOfWork interface which contains mappings to all of our repositories, like so:

public interface IUnitOfWork : IDisposable
{
    IRepository<Client> ClientsRepo { get; }
    IRepository<ConfigValue> ConfigValuesRepo { get; }
    IRepository<TestRun> TestRunsRepo { get; }
    //Etc...
}

Our IRepository class looks like this:

public interface IRepository<T>
{
    T getByID(int id);
    void Add(T Item);
    void Delete(T Item);
    void Attach(T Item);
    void Update(T Item);
    int Count();
}

My issue is that I'm trying to test a method that makes use of getById() , however this method is accessed through an IUnitOfWork object, like this:

public static TestRun getTestRunByID(IUnitOfWork database, int testRun)
{
    TestRun testRun = database.TestRunsRepo.getByID(testRun);
    return testRun;
}

In my test I have mocked 2 things; IUnitOfWork and IRepository . I have configured the IRepository so that it returns a TestRun item, however I can't actually make use of this repo since in the getTestRunByID() method it gets its own repo from the IUnitOfWork object. As a result this causes a NullReferenceException .

I have tried adding my repo to the IUnitOfWork's repo but it will not compile since all repos are marked as { get; } only. My test is:

[TestMethod]
public void GetTestRunById_ValidId_TestRunReturned()
{
    var mockTestRunRepo = new Mock<IRepository<TestRun>>();
    var testDb = new Mock<IUnitOfWork>().Object;
    TestRun testRun = new TestRun();
    mockTestRunRepo.Setup(mock => mock.getByID(It.IsAny<int>())).Returns(testRun);

    //testDb.TestRunsRepo = mockTestRunRepo; CAN'T BE ASSIGNED AS IT'S READ ONLY

    TestRun returnedRun = EntityHelper.getTestRunByID(testDb, 1);     
}

How can I get my IUnitOfWork's repo to not throw a NullReferenceException ?

You can't assign to a mock, you need to configure the properties via a Setup.


Instead of:

testDb.Setup(m => m.TestRunsRepo).Returns(mockTestRunRepo.Object);

Try:

testDb.SetupGet(m => m.TestRunsRepo).Returns(mockTestRunRepo.Object);

or

 testDb.SetupGet(m => m.TestRunsRepo).Returns(mockTestRunRepo.Object); 

I think you'll want something like this in your arrange:

testDb.Setup(n => n.TestRunsRepo).Returns(mockTestRunRepo.Object);

You're trying to assign something to the mocks object when it's far easier to just set the mock up and have it return what you want that way.

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