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

泪湿孤枕 提交于 2019-12-10 17:46:09

问题


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?


回答1:


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


Instead of:
testDb.TestRunsRepo = mockTestRunRepo;

Try:

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

or

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



回答2:


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.



来源:https://stackoverflow.com/questions/34789144/mocking-an-interface-which-is-get-only-moq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!