Проблема с тестированием FirstOrDefaultAsync() в моем примере кода
У меня есть метод ниже, в котором я получаю идентификатор пользователя по имени пользователя, и я написал тесты для этого. Однако тесты не работают при использовании FirstOrDefaultAsync(). Если я переключусь на FirstOrDefault(), тесты будут работать нормально. Вот код:
Тестируемый метод:
public async Task GetUserId(string userName)
{
return await _unitofWork.Repository().Entities
.Where(u => u.UserName == userName)
.Select(i => i.Id)
.FirstOrDefaultAsync();
}
Тестовый код:
[Fact]
public async Task GetUserIdTests()
{
//Arrange
var userEntity= new List
{
new UserEntity
{
UserName = "testuser", Id = 1
}
};
var repositoryMock = new Mock();
repositoryMock.Setup(r => r.Entities).Returns(new TestAsyncEnumerable(systemUsers).AsQueryable());
_unitOfWorkMock.Setup(u => u.Repository()).Returns(repositoryMock.Object);
var service= new service(_userContextMock.Object,_vaultServiceMock.Object);
//Act
var result = await service.GetUserId("testuser");
//Assert
Assert.NotEqual(0, result);
}
Проблема:
Это всего лишь пример, который я создал для проверки метода FirstOrDefaultAsync(), но он не работает. Тест работает правильно при использовании FirstOrDefault(), но завершается неудачей при использовании FirstOrDefaultAsync().
Поддерживающий код:
Здесь — это класс TestAsyncEnumerable, который я использую для поддержки асинхронных операций в тесте:
public class TestAsyncEnumerable : EnumerableQuery, IAsyncEnumerable, IQueryable
{
public TestAsyncEnumerable(IEnumerable enumerable) : base(enumerable) { }
public TestAsyncEnumerable(Expression expression) : base(expression) { }
public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new TestAsyncEnumerator(this.AsEnumerable().GetEnumerator());
}
IAsyncEnumerator IAsyncEnumerable.GetAsyncEnumerator(CancellationToken cancellationToken)
{
return GetAsyncEnumerator(cancellationToken);
}
IQueryProvider IQueryable.Provider => new TestAsyncQueryProvider(this);
}
public class TestAsyncEnumerator : IAsyncEnumerator
{
private readonly IEnumerator _inner;
public TestAsyncEnumerator(IEnumerator inner)
{
_inner = inner;
}
public ValueTask DisposeAsync()
{
_inner.Dispose();
return ValueTask.CompletedTask;
}
public ValueTask MoveNextAsync()
{
return new ValueTask(_inner.MoveNext());
}
public T Current => _inner.Current;
}
public class TestAsyncQueryProvider : IAsyncQueryProvider
{
private readonly IQueryProvider _inner;
public TestAsyncQueryProvider(IQueryProvider inner)
{
_inner = inner;
}
public IQueryable CreateQuery(Expression expression)
{
return new TestAsyncEnumerable(expression);
}
public IQueryable CreateQuery(Expression expression)
{
return new TestAsyncEnumerable(expression);
}
public object Execute(Expression expression)
{
return _inner.Execute(expression);
}
public TResult Execute(Expression expression)
{
return _inner.Execute(expression);
}
public TResult ExecuteAsync(Expression expression, CancellationToken cancellationToken)
{
return Execute(expression);
}
public IAsyncEnumerable ExecuteAsync(Expression expression)
{
return new TestAsyncEnumerable(expression);
}
}
Вопрос:
Что может быть причиной сбоя теста при использовании FirstOrDefaultAsync()? Что-то не так с тем, как я реализовал класс TestAsyncEnumerable или как настроен асинхронный тест?
**Error:**
Message:
System.ArgumentException : Argument expression is not valid
Stack Trace:
IQueryProvider.Execute[TElement](Expression expression)
TestAsyncQueryProvider`1.Execute[TResult](Expression expression) line 72
TestAsyncQueryProvider`1.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken) line 78
EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
EntityFrameworkQueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
Подробнее здесь: https://stackoverflow.com/questions/789 ... faultasync
Устранение проблем с асинхронным методом в модульных тестах: устранение сбоев FirstOrDefaultAsync() ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение