EF6 - 无法模拟ObjectResult <T>的返回值进行单元测试

dga*_*ian 4 c# unit-testing moq mocking entity-framework-6

我在一个方法中有类似于此的代码,我正在尝试进行单元测试:

return _context.usp_get_Some_Data(someStringParam).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

存储的proc调用返回类型:

ObjectResult<usp_get_Some_Data_Result>. 
Run Code Online (Sandbox Code Playgroud)

在我的单元测试中,我正在尝试做这样的事情(使用NUnit和Moq):

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

但是,我无法创建ObjectResult的实例(这是System.Data.Entity.Core.Objects.ObjectResult <T>,而不是旧的System.Data.Objects实例).它没有公共无参数构造函数,但文档说它有一个受保护的构造函数.从我的测试来看,他的文档似乎是不正确的.

我试过的: 我尝试在构造函数上创建派生类并调用base(),我也尝试使用反射(Activator.CreateInstance和使用NonPublic的BindingFlags调用ConstructorInfo,所有这些都失败了(从我的调试中可以看出,该类型确实有三个私有构造函数,所有这些构造函数都有3个或更多参数,但不幸的是,这似乎是一个很大的努力来弄清楚这些参数实际需要什么).

我还尝试创建一个IEnumberable <usp_get_Some_Data_Result>并将其转换为ObjectResult <usp_get_Some_Data_Result>但是转换失败了.另外,我尝试过类似的东西

var mockObjectResult = new Mock<ObjectResult<usp_get_Some_Data_Result>>();
Run Code Online (Sandbox Code Playgroud)

几乎所有我试过的都失败了,关于默认构造函数不可用的类似错误.

问题:有没有办法为单元测试创​​建一个ObjectResult <T>实例,或者是否可以创建任何可以成功转换为ObjectResult <T>的其他类型?

for*_*rir 7

也许我错过了什么,但你不能这样做:

class TestableObjectResult<T> : ObjectResult<T>
{
}
Run Code Online (Sandbox Code Playgroud)

然后在你的测试中:

var mockObjectResult = new Mock<TestableObjectResult<usp_get_Some_Data_Result>>();
Run Code Online (Sandbox Code Playgroud)

MockObject确实有一个受保护的构造函数,你没有必要做任何事情来调用它,因为它没有任何参数,当你构造可测试版本时,自动连线会处理它,所以我不是确定你的意思是"在构造函数上调用base()"......

如果我右键单击ObjectResult并选择goto定义,文件的顶部如下所示:

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();
Run Code Online (Sandbox Code Playgroud)