2017-10-19 120 views
3

我有entityframework回購,它從sqldb獲取行程信息。我創建了repo,並在構造函數中注入了dbContext並使用該上下文執行數據庫操作。爲EF dbcontext設置模擬對象以測試存儲庫方法

public class WorldRepository : IWorldRepository 
    { 
     private WorldContext _context; 

     public WorldRepository(WorldContext context) 
     { 
      _context = context; 
     } 

     public void AddSop(string tripName, Stop newStop) 
     { 
      var trip = GetTipByName(tripName); 

      if (trip != null) 
      { 
       trip.Stops.Add(newStop); 
       _context.Stops.Add(newStop); 
      } 
     } 

     public void AddTrip(Trip trip) 
     { 
      _context.Add(trip); 
     } 

     public IEnumerable<Trip> GetAllTrips() 
     { 
      return _context.Trips.ToList(); 
     } 
} 

現在我正在嘗試使用最小起訂量,但這沒有幫助。我無法測試任何寫入我的方法的邏輯,因爲它查詢的是模擬對象而不是我的實現。

// private Mock<IWorldRepository> _mockWorld; 

     [TestMethod] 
     public void Test_AddTrips() 
     { 
      //Arrange 
      // WorldRepository repo = new WorldRepository(null); 

      Mock<IWorldRepository> _mockWorld = new Mock<IWorldRepository>(); 
      var repo = _mockWorld.Object; 

      //Act 
      repo.AddSop("Sydney", new Stop 
      { 
       Arrival = DateTime.Now, 
       Id = 2, 
       Latittude = 0.01, 
       Longitude = 0.005, 
       Name = "Test Trip", 
       Order = 5 
      }); 

      repo.SaveChangesAsync(); 

      var count = repo.GetAllTrips().Count(); 

      //Assert 
      Assert.AreEqual(1, count); 


     } 

這是WorldContext的代碼。

public class WorldContext:DbContext 
    { 
     private IConfigurationRoot _config; 

     public WorldContext(IConfigurationRoot config,DbContextOptions options) 
      :base(options) 
     { 
      _config = config; 
     } 

     public DbSet<Trip> Trips { get; set; } 
     public DbSet<Stop> Stops{ get; set; } 

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
     { 
      base.OnConfiguring(optionsBuilder); 
      optionsBuilder.UseSqlServer(_config["ConnectionStrings:WorldCotextConnection"]); 
     } 
    } 
+2

您需要使用WorldRepository類和模擬dbcontext。您還可以發佈WorldContext的代碼。 – Simsons

+2

您應該嘲笑WorldContext並將其傳遞到WorldRepository中。 – HiredMind

+1

Microsoft爲異步模擬提供了一個實現。 https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx – Jasen

回答

2

我假設你正在試圖嘲弄WorldContextand與您的回購情況下使用它,所以我們需要模擬,第一。要做到這一點,請爲worlddbcontext創建一個接口。

public interface IWorldContext 
    { 
     DbSet<Stop> Stops { get; set; } 
     DbSet<Trip> Trips { get; set; } 
    } 

現在你想要的是嘲笑依賴和測試主題。

在這種情況下,您想模擬WorldDbContext,模擬DbSet<Stop>並測試AddSop方法。

要創建一個模擬DbSet,我在引用MSDN, EF Testing with Mocking framework也提到了Jasen的註釋。

private Mock<IWorldContext> _context; 
private WorldRepository _repo; 

     [TestMethod] 
     public void Test_AddTrips() 
     { 
      ////Arrange   

      var data = new List<Stop> { 
       new Stop 
       { 
        Arrival = DateTime.Now.AddDays(-15), 
        Id = 1, 
        Latittude = 0.05, 
        Longitude = 0.004, 
        Name = "Test Trip01", 
        Order = 1 
       }, 
        new Stop 
       { 
        Arrival = DateTime.Now.AddDays(-20), 
        Id = 2, 
        Latittude = 0.07, 
        Longitude = 0.015, 
        Name = "Test Trip02", 
        Order = 2 
       } 

      }.AsQueryable(); 

      var mockSet = new Mock<DbSet<Stop>>(); 
      mockSet.As<IQueryable<Stop>>().Setup(m => m.Provider).Returns(data.Provider); 
      mockSet.As<IQueryable<Stop>>().Setup(m => m.Expression).Returns(data.Expression); 
      mockSet.As<IQueryable<Stop>>().Setup(m => m.ElementType).Returns(data.ElementType); 
      mockSet.As<IQueryable<Stop>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); 


      _context = new Mock<IWorldContext>(); 

      //Set the context of mock object to the data we created. 
      _context.Setup(c => c.Stops).Returns(mockSet.Object); 

      //Create instance of WorldRepository by injecting mock DbContext we created 
      _repo = new WorldRepository(_context.Object);  


      //Act 
      _repo.AddSop("Sydney", 
       new Stop 
       { 
        Arrival = DateTime.Now, 
        Id = 2, 
        Latittude = 0.01, 
        Longitude = 0.005, 
        Name = "Test Trip", 
        Order = 5 
       }); 

      _repo.SaveChangesAsync(); 

      var count = _repo.GetAllTrips().Count(); 

      //Assert 
      Assert.AreEqual(3, count); 


     } 

另外,有一個輝煌的module上的多個視線上Testing Repository模塊,他非常詳細地解釋了這個(僅僅是一個參考,沒有背書或其他任何東西)的Mosh

1

如果你想測試WorldRepository,你需要創建這種類型的真實對象,並模擬它的所有外部依賴關係 - WorldContext在你的情況。

爲測試所以正確的設置應該是這樣的:

var contextMock = new Mock<WorldContext>(); 
contextMock.Setup(...); //setup desired behaviour 
var repo = new WorldRepository(contextMock.Object);