I have some codes like below, I want to write unit tests my method. But I'm stuck in async methods. Can you help me please ?
public class Panel { public int Id { get; set; } [Required] public double Latitude { get; set; } public double Longitude { get; set; } [Required] public string Serial { get; set; } public string Brand { get; set; } } public class CrossSolarDbContext : DbContext { public CrossSolarDbContext() { } public CrossSolarDbContext(DbContextOptions<CrossSolarDbContext> options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { } } public interface IGenericRepository<T> { Task<T> GetAsync(string id); IQueryable<T> Query(); Task InsertAsync(T entity); Task UpdateAsync(T entity); } public abstract class GenericRepository<T> : IGenericRepository<T> where T : class, new() { protected CrossSolarDbContext _dbContext { get; set; } public async Task<T> GetAsync(string id) { return await _dbContext.FindAsync<T>(id); } public IQueryable<T> Query() { return _dbContext.Set<T>().AsQueryable(); } public async Task InsertAsync(T entity) { _dbContext.Set<T>().Add(entity); await _dbContext.SaveChangesAsync(); } public async Task UpdateAsync(T entity) { _dbContext.Entry(entity).State = EntityState.Modified; await _dbContext.SaveChangesAsync(); } } public interface IPanelRepository : IGenericRepository<Panel> { } public class PanelRepository : GenericRepository<Panel>, IPanelRepository { public PanelRepository(CrossSolarDbContext dbContext) { _dbContext = dbContext; } } [Route("[controller]")] public class PanelController : Controller { private readonly IPanelRepository _panelRepository; public PanelController(IPanelRepository panelRepository) { _panelRepository = panelRepository; } // GET panel/XXXX1111YYYY2222 [HttpGet("{panelId}")] public async Task<IActionResult> Get([FromRoute] string panelId) { Panel panel = await _panelRepository.Query().FirstOrDefaultAsync(x => x.Serial.Equals(panelId, StringComparison.CurrentCultureIgnoreCase)); if (panel == null) return NotFound(); return Ok(panel); } } public class PanelControllerTests { private readonly PanelController _panelController; private static readonly Panel panel = new Panel { Id = 1, Brand = "Areva", Latitude = 12.345678, Longitude = 98.7655432, Serial = "AAAA1111BBBB2222" }; private readonly IQueryable<Panel> panels = new List<Panel>() { panel }.AsQueryable(); private readonly Mock<IPanelRepository> _panelRepositoryMock = new Mock<IPanelRepository>(); public PanelControllerTests() { _panelRepositoryMock.Setup(x => x.Query()).Returns(panels); // I also tried this. I got another error 'Invalid setup on an extension method: x => x.FirstOrDefaultAsync<Panel>(It.IsAny<Expression<Func<Panel, Boolean>>>(), CancellationToken)' // _panelRepositoryMock.As<IQueryable<Panel>>().Setup(x => x.FirstOrDefaultAsync(It.IsAny<Expression<Func<Panel, bool>>>(), default(CancellationToken))).ReturnsAsync(panel); _panelController = new PanelController(_panelRepositoryMock.Object); } [Fact] public async Task Register_ShouldInsertOneHourElectricity() { IActionResult result = await _panelController.Get("AAAA1111BBBB2222"); Assert.NotNull(result); var createdResult = result as CreatedResult; Assert.NotNull(createdResult); Assert.Equal(201, createdResult.StatusCode); } }
I'm getting this error
The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IEntityQueryProvider can be used for Entity Framework asynchronous operations.
I think that I need to mock 'FirstOrDefaultAsync' but I'm not sure and I don't know how to do. I tried something, however it couldn't be compiled.