Tôi đang thử .NET Core lần đầu tiên và xem Moq có thể được sử dụng như thế nào trong thử nghiệm đơn vị. Ra khỏi hộp, các bộ điều khiển được tạo ra nơi ApplicationDbContext là các thông số để các nhà xây dựng như thế này:Làm cách nào để Moq ApplicationDbContext trong .NET Core
public class MoviesController : Controller
{
private readonly ApplicationDbContext _context;
public MoviesController(ApplicationDbContext context)
{
_context = context;
}
Đây là bài kiểm tra đơn vị mà tôi bắt đầu với khi thử nghiệm bộ điều khiển:
[TestClass]
public class MvcMoviesControllerTests
{
[TestMethod]
public async Task MoviesControllerIndex()
{
var mockContext = new Mock<ApplicationDbContext>();
var controller = new MoviesController(mockContext.Object);
// Act
var result = await controller.Index();
// Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
}
Nhưng sau đó Tôi nhận ra ApplicationDbContext là một lớp cụ thể và nó không có một constructor parameterless nên test sẽ không hoạt động. Nó cho tôi lỗi: Không thể tìm thấy constructor parameterless.
Có lẽ đây có thể là một câu hỏi nhắm vào Moq hơn là liên quan đến .NET Core, nhưng tôi cũng mới với Moq nên tôi không chắc chắn cách tiếp tục. Đây là cách mã ApplicationDbContext được tạo khi tôi tạo dự án:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
public DbSet<Movie> Movie { get; set; }
}
Tôi cần thay đổi gì để thử nghiệm đơn vị của mình thành công?
UPDATE:
tôi phát hiện ra từ https://msdn.microsoft.com/en-us/magazine/mt703433.aspx mà bạn có thể cấu hình EF Core để sử dụng một cơ sở dữ liệu trong bộ nhớ cho kiểm tra đơn vị. Vì vậy, tôi đã thay đổi thử nghiệm đơn vị của mình để trông giống như sau:
[TestMethod]
public async Task MoviesControllerIndex()
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseInMemoryDatabase();
var _dbContext = new ApplicationDbContext(optionsBuilder.Options);
var controller = new MoviesController(_dbContext);
// Act
var result = await controller.Index();
// Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
}
Thử nghiệm này hiện thành công. Nhưng đây có phải là cách thích hợp để làm điều này không? Rõ ràng, tôi hoàn toàn loại bỏ các Mocking ApplicationDbContext với Moq! Hoặc là có một giải pháp cho vấn đề này bằng cách sử dụng Moq.
Ngay cả với bộ nhớ trong DbContext bạn về cơ bản đang thực hiện thử nghiệm tích hợp mà vẫn cần thiết. Tuy nhiên, bạn từ quan điểm thiết kế, nên có các lớp của bạn phụ thuộc vào trừu tượng và không phải concretions. Tạo một giao diện cho thấy các chức năng bạn cần và có bối cảnh cụ thể của bạn kế thừa từ đó. – Nkosi
Tôi đồng ý với @Nkosi đây hiện là thử nghiệm tích hợp hiệu quả. Chắc chắn là 'ApplicationDbContext' thực hiện' IdentityDbContext ', bạn có thể đưa giao diện vào bộ điều khiển của bạn và sau đó giả lập nó thay thế không? –
Corporalis