I am writing a Unit Test and need to mock Entity Framework's .FromSqlRaw method. When the method is executed in the class under test, it throws following exception:
System.InvalidOperationException: There is no method 'FromSqlOnQueryable' on type 'Microsoft.EntityFrameworkCore.RelationalQueryableExtensions' that matches the specified arguments.
Following is class under test:
public class PowerConsumptionRepository : IPowerConsumptionRepository
{
private readonly IDatabaseContext _databaseContext;
private readonly IDateTimeHelper _dateTimeHelper;
public PowerConsumptionRepository(IDatabaseContext databaseContext, IDateTimeHelper dateTimeHelper)
{
_databaseContext = databaseContext;
_dateTimeHelper = dateTimeHelper;
}
public List<IntervalCategoryConsumptionModel> GetCurrentPowerConsumption(string siteId)
{
var currentDate = _dateTimeHelper
.ConvertUtcToLocalDateTime(DateTime.UtcNow, ApplicationConstants.LocalTimeZone)
.ToString("yyyy-MM-dd");
var currentDateParameter = new SqlParameter("currentDate", currentDate);
var measurements = _databaseContext.IntervalPowerConsumptions
.FromSqlRaw(SqlQuery.CurrentIntervalPowerConsumption, currentDateParameter)
.AsNoTracking()
.ToList();
return measurements;
}
}
Unit Test:
public class PowerConsumptionRepositoryTests
{
[Fact]
public void TestTest()
{
var data = new List<IntervalCategoryConsumptionModel>
{
new IntervalCategoryConsumptionModel
{
Id = 1,
Hvac = 10
},
new IntervalCategoryConsumptionModel
{
Id = 1,
Hvac = 10
}
}.AsQueryable();
var dateTimeHelper = Substitute.For<IDateTimeHelper>();
dateTimeHelper.ConvertUtcToLocalDateTime(Arg.Any<DateTime>(), Arg.Any<string>()).Returns(DateTime.Now);
var mockSet = Substitute.For<DbSet<IntervalCategoryConsumptionModel>, IQueryable<IntervalCategoryConsumptionModel>>();
((IQueryable<IntervalCategoryConsumptionModel>)mockSet).Provider.Returns(data.Provider);
((IQueryable<IntervalCategoryConsumptionModel>)mockSet).Expression.Returns(data.Expression);
((IQueryable<IntervalCategoryConsumptionModel>)mockSet).ElementType.Returns(data.ElementType);
((IQueryable<IntervalCategoryConsumptionModel>)mockSet).GetEnumerator().Returns(data.GetEnumerator());
var context = Substitute.For<IDatabaseContext>();
context.IntervalPowerConsumptions = (mockSet);
var repo = new PowerConsumptionRepository(context, dateTimeHelper);
var result = repo.GetCurrentPowerConsumption(Arg.Any<string>());
result.Should().NotBeNull();
}
}
.FromSqlRaw
executes SQL query. – AffectionatePowerConsumptionRepository
you should probably use a "real" database. I recently came across the post Avoid In-Memory Databases for Tests by Jimmy Bogard which might give you some more perspective on this issue. – Gilemette