简体   繁体   English

使用Moq和Autofac进行单元测试中实体框架的扩展方法

[英]Extension methods of Entity Framework in unit test using Moq and Autofac

I'm mocking a DbSet from Entify Framework. 我正在从Entify Framework嘲笑DbSet。 I want to use its extension method ToListAsync . 我想使用它的扩展方法ToListAsync This is how I do it and below a result of my attempt (regular ToList works): 这就是我这样做的方式,并且低于我的尝试结果(常规ToList工作):

IQueryable<DbUser> userData = MockedData.Instance.Users; // this is just a property to get custom IQueryable set of data for testing

var dbSetMock = new Mock<DbSet<DbUser>>();

dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.Provider).Returns(userData.Provider);
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.Expression).Returns(userData.Expression);
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.ElementType).Returns(userData.ElementType);
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.GetEnumerator()).Returns(userData.GetEnumerator());

/*
I've put it here so you can see how I tried to approach my problem
dbSetMock.Setup(x => x.ToListAsync())
    .Returns(Task.FromResult(userData.ToList()));
*/

var testAsync = dbSetMock.Object.ToListAsync();
var testRegular = dbSetMock.Object.ToList();

Results: 结果:

The variable testRegular has value as expected. 变量testRegular具有预期的值。 But the variable testAsync has value like this: 但变量testAsync值如下:

测试ToListAsync结果

When I uncomment the part where I try to setup ToListAsync to return anything I get an exception like this: 当我取消注释我尝试设置ToListAsync以返回任何内容的部分时,我得到如下的异常:

{"Expression references a method that does not belong to the mocked object: x => x.ToListAsync<DbUser>()"}

I'd appreciate any suggestions. 我很感激任何建议。 Should I switch to Fakes maybe? 我应该切换到Fakes吗? is such functionality supported there? 是否支持这样的功能?

I found and used this code with success: 我成功找到并使用了这段代码:

dbSetMock.As<IDbAsyncEnumerable<DbUser>>()
    .Setup(m => m.GetAsyncEnumerator())
    .Returns(new AsyncEnumerator<DbUser>(userData.GetEnumerator()));

with the following support class (note use of C#6 shorthand features): 使用以下支持类(注意使用C#6速记功能):

class AsyncEnumerator<T> : IDbAsyncEnumerator<T>
{
    private readonly IEnumerator<T> _inner;
    public AsyncEnumerator(IEnumerator<T> inner)
    {
        _inner = inner;
    }
    public void Dispose() => _inner.Dispose();
    public Task<bool> MoveNextAsync(CancellationToken cancellationToken) => Task.FromResult(_inner.MoveNext());
    public T Current => _inner.Current;
    object IDbAsyncEnumerator.Current => Current;
}

The root cause of the error is that Moq cannot mock static methods, at least for now. 错误的根本原因是Moq不能模拟静态方法,至少目前是这样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM