I have a test case to test my EF repository getallasync call as follows:
// Arrange
var systemsData = new List<SystemEntity>
{
new SystemEntity { SystemId = 1, Full_Year_Standings = true, Season_StartDate = DateTime.Now, Season_EndDate = DateTime.Now },
new SystemEntity { SystemId = 2, Full_Year_Standings = false, Season_StartDate = DateTime.Now, Season_EndDate = DateTime.Now },
new SystemEntity { SystemId = 3, Full_Year_Standings = true, Season_StartDate = DateTime.Now, Season_EndDate = DateTime.Now }
};
var mockContext = Mock.Create<BetCenterContext>(Behavior.Loose);
Mock.Arrange(() => mockContext.Set<SystemEntity>()).ReturnsCollection(systemsData);
var systemRepository = new SystemRepository(mockContext);
// Act
var result = await systemRepository.GetAllAsync();
Calling the following method:
public async Task<List<SystemEntity>> GetAllAsync()
{
var collToReturn = await _context.Set<SystemEntity>().ToListAsync();
return collToReturn;
}
The arranged mock returns a null result and throws InvalidOperationException - The source 'IQueryable' doesn't IAsyncEnumerable...'
How do I arrange the mock to return the correct value?
Since the initial question I have learned a few different ways to convert my test data to a IAsyncEnumerable. Among them writing a static method that yields the test data. Also using the ToAsyncEnumerable method call in System.Linq.Async library. Both give me the test object I want.
The problem now is that there doesn't seem to be any way to return the IAsyncEnumerable test object in the Telerik Mock.Arrange methods. ReturnsCollection throws a compile error, as does Returns (which isn't a fit but I tried it anyways).
Any ideas?
With little help from the extension methods like the following you can achieve the desired conversion, here is the code:
public static class IEnumeratorExtension { public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerator<T> iterator) { while (iterator.MoveNext()) { await Task.Yield(); yield return iterator.Current; } } public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerator iterator) { while (iterator.MoveNext()) { await Task.Yield(); yield return (T)iterator.Current; } } }
Hi
This does not seem to work.
Trying Ivo's suggestion, but that just fails to compile.
[Fact] public void ShouldReturnEntity() { var db = Mock.Create<MyModel.MyModel>(); Mock.Arrange(() => db.SomeEntities).ReturnsCollection(someEntities); var entity = db.SomeEntities.SingleAsync(x => x.Id == 1); Assert.NotNull(entity); }
Having any async method call like SingleAsync above will give you and exception like
This is a trivial example.
One route is to mock SingleAsync call, but our code is more complex and mocking every async Linq call would be a nightmare (and not sure its possible with the Linq-queries we have).
Is there any way to get this to work ??
Adding a the simple example source as attachment.