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>?
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();
As noted, I'm adding this answer to cover creating the Enumerator so the above can actually test some fake data:
Within the [TestFixture] class, create a method like the following:
private static IEnumerator<usp_get_Some_Data_Result> GetSomeDataResultEnumerator()
{
yield return FakeSomeDataResult.Create(1, true);
yield return FakeSomeDataResult.Create(2, false);
}
As provided in the previous answer, this handy little wrapper class allows instantiating the ObjectResult:
public class TestableObjectResult<T> : ObjectResult<T> { }
As provided in the previous answer, within the [SetUp] method:
var mockObjectResult = new Mock<TestableObjectResult<usp_get_Some_Data_Result>>();
Following this new Mock creation, set it up to return the Enumerator:
mockObjectResult.Setup(d => d.GetEnumerator()).Returns(GetSomeDataResultEnumerator());
Now the OP can return some fake data from the mockContext without it throwing a null reference exception when trying to get the enumerator:
mockContext.Setup(m => m.usp_get_Some_Data(It.IsAny<string>()))
.Returns(mockObjectResult);
BTW, I'm just using a helper class to construct my fake data, to eliminate redundancy:
public static class FakeSomeDataResult
{
public static usp_get_Some_Data_Result Create(int index)
{
return new usp_get_Some_Data_Result
{
SomeFriendlyNameProperty = string.Format("Some Data Result {0}", index),
};
}
}
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With