NSubstitute DbSet / IQueryable

后端 未结 5 1451
心在旅途
心在旅途 2020-12-02 12:12

So EntityFramework 6 is a lot better testable then previous versions. And there are some nice examples on the internet for frameworks like Moq, but the case is, I prefer usi

5条回答
  •  情话喂你
    2020-12-02 12:53

    I wrote a wrapper about a year ago around the same code you are referencing from Testing with Your Own Test Doubles (EF6 onwards). This wrapper can be found on GitHub DbContextMockForUnitTests. The purpose of this wrapper is to reduce the amount of repetitive/duplicate code needed to setup unit tests that make use of EF where you want to mock that DbContext and DbSets. Most of the mock EF code you have in the OP can reduced down to a 2 lines of code (and only 1 if you are using DbContext.Set instead of DbSet properties) and the mock code is then called in the wrapper.

    To use it copy and include the files in folder MockHelpers to your Test project.

    Here is an example test using what you had above, notice that there is now only 2 Lines of code are needed to setup the mock DbSet on the mocked DbContext.

    public void GetAllBlogs_orders_by_name()
    {
      // Arrange
      var data = new List
      {
         new Blog { Name = "BBB" },
         new Blog { Name = "ZZZ" },
         new Blog { Name = "AAA" },
      };
    
      var mockContext = Substitute.For();
    
      // Create and assign the substituted DbSet
      var mockSet = data.GenerateMockDbSet();
      mockContext.Blogs.Returns(mockSet);
    
      // act
    }
    

    It is just as easy to make this a test that invokes something that uses the async/await pattern like .ToListAsync() on the DbSet.

    public async Task GetAllBlogs_orders_by_name()
    {
      // Arrange
      var data = new List
      {
         new Blog { Name = "BBB" },
         new Blog { Name = "ZZZ" },
         new Blog { Name = "AAA" },
      };
    
      var mockContext = Substitute.For();
    
      // Create and assign the substituted DbSet
      var mockSet = data.GenerateMockDbSetForAsync(); // only change is the ForAsync version of the method
      mockContext.Blogs.Returns(mockSet);
    
      // act
    }
    

提交回复
热议问题