How can I mock the Entity Framework 6 ObjectResult with Moq so that I can unit test my code that relies on an EF database connection?
Having read numerous questions and answers along these lines, and gleaned many nuggets from what I've read, I've implemented what I feel is a reasonably elegant solution and felt that I should share it, since the community here helped me get there. Thus, I'll proceed to answer this question, and potentially open myself up to some mockery (pun intended):
First of all, ObjectResult does not have a public parameterless constructor, thus it is necessary first to create a testable wrapper for ObjectResult. The answer by @forsvarir (https://stackoverflow.com/users/592182/forsvarir) in this post got me thinking correctly along these lines (EF6 - Cannot Mock Return Value for ObjectResult<T> for Unit Test):
Of course, the DbContext needs to be mocked. Your method then needs to be set up to return the appropriate mocked enumerator. For convenience, I created a method to help in the creation of the Mock EF Results to keep my test code from getting cluttered and redundant. This can live in some utilitarian class that you have for your tests, though I just included it as a private method here. The key thing here being that the mock object result needs to return an enumerator when GetEnumerator is called:
The Enumerators class that I created for handing back the enumerator whenever the function is called on the mock simply looks like this. In this example I have the fake enumerator creating 5 rows of data:
And, as you can see, this simply relies on a class that creates each fake row of data:
Being able to mock at this level really enables my ability to do BDD and only mock or fake the peripheries, never mocking or faking my code, so I get complete(r) test coverage.
Hope this helps those who, like me, were looking for a nice clean way to mock Entity Framework 6.
I have run into this problem many times
My solution is to mock a ObjectResult's GetEnumeartor method. This can easily be done within a test method will very little overhead
for example
say we have a repo method that calls a DBContext method that returns a
ObjectResult<string>
. The repo method would get the resulting valuestring
by enumearting theObjectResult<string>
with maybeobjResult.FirstOrDefault()
. As you know the LINQ method just calls into theObjectResult
's enumeartor. Therefore, mocking theGetEnumeartor()
function of theObjectResult
will do the trick. Any enumeartion of teh result will return our mocked enumerator.Example
Here is a simple a simple func that produces an
IEnumerator<string>
from astring
. This can be inlined with an anonymous method but it makes it harder to read for illustration purposes here.this func can be called by passing a string like this
this may make it easier for us to get the
IEnumerator<string>
we expect theObjectResult<string>
'sGetEnumerator()
method to return so any repo method that calls the ObjectResult will receive our stringNo we have a mocked
ObjectResult<string>
that we can pass into a repo method inferring our method will eventually call into the enumerator in some way and will get ourshouldBe
value.