这个问题我遇到过很多次了
我的解决方案是模拟 ObjectResult 的 GetEnumeartor 方法。这可以很容易地在一个测试方法中完成,开销很小
例如
假设我们有一个调用 DBContext 方法的 repo 方法,该方法返回一个ObjectResult<string>。 repo 方法将通过枚举ObjectResult<string> 和objResult.FirstOrDefault() 来获得结果值string。如您所知,LINQ 方法只是调用ObjectResult 的枚举器。因此,模拟ObjectResult 的GetEnumeartor() 函数就可以了。任何枚举结果都将返回我们模拟的枚举器。
示例
这是一个简单的函数,它从 string 生成 IEnumerator<string>。这可以用匿名方法内联,但为了便于说明,这里更难阅读。
var f = new Func< string,IEnumerator< string> >( s => ( ( IEnumerable< string > )new []{ s } ).GetEnumerator( ) );
这个函数可以通过传递这样的字符串来调用
var myObjResultReturnEnum = f( "some result" );
这可能使我们更容易获得 IEnumerator<string>,我们希望 ObjectResult<string> 的 GetEnumerator() 方法返回,因此任何调用 ObjectResult 的 repo 方法都将收到我们的字符串
// arrange
const string shouldBe = "Hello World!";
var objectResultMock = new Mock<ObjectResult<string>>();
objectResultMock.Setup( or => or.GetEnumerator() ).Returns(() => myObjResultReturnEnum );
不,我们有一个模拟的 ObjectResult<string>,我们可以将它传递给一个 repo 方法,从而推断我们的方法最终会以某种方式调用枚举器并获得我们的 shouldBe 值。
var contextMock = new Mock<SampleContext>( );
contextMock.Setup( c => c.MockCall( ) ).Returns( ( ) => objectResultMock.Object );
// act
var repo = new SampleRepository( contextMock.Object );
var result = repo.SampleSomeCall( );
// assert
Assert.IsNotNull(result);
Assert.AreEqual(shouldBe, result);