EF6 - Cannot Mock Return Value for ObjectResult for Unit Test

c# entity-framework-6 mocking moq unit-testing

Question

I have code similar to this in a method that I'm trying to unit test:

return _context.usp_get_Some_Data(someStringParam).FirstOrDefault();

The stored proc call return type:

ObjectResult<usp_get_Some_Data_Result>. 

In my unit test, I'm trying to do something like this (using NUnit and Moq):

var procResult = new ObjectResult<usp_get_Some_Data_Result>();
mockContext.Setup(m => m.usp_get_Some_Data(It.IsAny<string>()))
    .Returns(procResult);

However, I'm not able to create an instance of ObjectResult (this is System.Data.Entity.Core.Objects.ObjectResult<T>, not the older System.Data.Objects one). It doesn't have a public parameterless constructor, but the documentation says it has a protected one. From my testing, he documentation appears to be incorrect.

What I've Tried: I've tried creating a derived class and calling base() on the constructor, and I've also tried using reflection (both Activator.CreateInstance and invoking the ConstructorInfo with BindingFlags of NonPublic, all of which have failed (it appears from my debugging this that the type does have three private constructors, all of which have 3 or more parameters, but unfortunately it looks like a major effort to figure out what is actually required for these parameters).

I've also tried creating an IEnumberable<usp_get_Some_Data_Result> and casting it to ObjectResult<usp_get_Some_Data_Result> but the cast fails. In addition, I've tried something like

var mockObjectResult = new Mock<ObjectResult<usp_get_Some_Data_Result>>();

Pretty much everything I've tried fails with a similar error about a default constructor not being available.

Question: Is there any way to create an instance of ObjectResult<T> for unit testing, or is there any other type that I can create that can be successfully cast to ObjectResult<T>?

1
4
6/26/2015 6:10:11 PM

Accepted Answer

Maybe I'm missing something, but can't you just do this:

class TestableObjectResult<T> : ObjectResult<T>
{
}

And then in your test:

var mockObjectResult = new Mock<TestableObjectResult<usp_get_Some_Data_Result>>();

MockObject does have a protected constructor, you don't really have to do anything to call it, since it doesn't have any parameters, the auto-wiring will take care of it when you construct the testable version, so I'm not sure what you mean by you're "calling base() on the constructor"...

If I right click on ObjectResult and select goto definition the top of the file looks like this:

public class ObjectResult<T> : ObjectResult, IEnumerable<T>, IEnumerable, IDbAsyncEnumerable<T>, IDbAsyncEnumerable
{
    // Summary:
    //     This constructor is intended only for use when creating test doubles that
    //     will override members with mocked or faked behavior. Use of this constructor
    //     for other purposes may result in unexpected behavior including but not limited
    //     to throwing System.NullReferenceException.
    protected ObjectResult();
7
6/26/2015 7:12:16 PM

Popular Answer

As @forsvarir mentioned, you can create a TestableObjectResult class and override the GetEnumerator() to return whatever you want.

Something like this:

private class TestableObjectResult : ObjectResult<Animal>
    {
        public override IEnumerator<Animal> GetEnumerator()
        {
            return new List<Animal>() { new Animal(), new Animal() }.GetEnumerator();
        }
    }


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow