问题
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