Test service class using moq in asp.net

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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);

}

Method 2

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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x