Reputation: 335
I have a service class like this:
public class CategoryService: ICategoryService
{
private myContext _context;
public CategoryService(myContext context)
{
_context = context;
}
public async Task<List<CategoryDTO>> GetCategories()
{
return (await _context.Categories.ToListAsync()).Select(c => new CategoryDTO
{
CategoryId = c.CategoryId,
CategoryName = c.CategoryName
}).ToList();
}
}
My context looks like this:
public DbSet<Category> Categories {get;set;}
My unit test for GetCategories()
is:
[Fact]
public void TestGetCategories()
{
//Arrange
Mock <myContext> moq = new Mock <myContext>();
var moqSet = new Mock<DbSet<Category>>();
moq.Setup(m => m.Categories).Returns(moqSet.Object);
CategoryService service = new CategoryService(moq.Object);
//Act
var result = service.GetCategories();
//Assert
Assert.NotNull(result);
}
But I am getting error for my unit test. It says:
System.NotSupportedException : Unsupported expression: m => m.Categories
Can someone help me to fix the Setup part?
Upvotes: 3
Views: 143
Reputation: 335
I finally could figure it out. As @PeterCsala mentioned, we can use "EntityFrameworkCore3Mock" You can find it here: https://github.com/huysentruitw/entity-framework-core3-mock
My unit test looks like this:
public DbContextOptions<ShoppingCartContext> dummyOptions { get; } = new DbContextOptionsBuilder<ShoppingCartContext>().Options;
[Fact]
public async Task TestGetCategories()
{
//Arrange
var dbContextMoq = new DbContextMock<ShoppingCartContext>(dummyOptions);
//Create list of Categories
dbContextMoq.CreateDbSetMock(x => x.Categories, new[]
{
new Category { CategoryId = 1, CategoryName = "Items" },
new Category { CategoryId = 2, CategoryName = "Fruits" }
});
//Act
CategoryService service = new CategoryService(dbContextMoq.Object);
var result = await service.GetCategories();
//Assert
Assert.NotNull(result);
}
Upvotes: 2
Reputation: 26362
You cannot use Moq with non overrideable properties. It needs to be either abstract or virtual and that's why you get the error.
Change the dbcontext
property Categories
to virtual and try again.
public virtual DbSet<Category> Categories {get;set;}
P.s. you don't need to do this when you mock interface methods, because they are inherently overridable.
Upvotes: 1