【发布时间】:2018-03-23 12:44:26
【问题描述】:
我为我的核心 1.0 应用程序添加了一个测试项目。在其中我有在构造函数中使用 dbContext 的存储库。
如何在测试项目中访问这个 dbContext 并正确注入?
这是我的 ApplicationDbContext 类:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ShoppingCartItem> ShoppingCartItems { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
}
这是我的单元测试方法:
[Fact]
public void ProductsGetAll()
{
//here i need to get acces to dbContext and inject it below
ProductRepository productRepository = new ProductRepository(dbContext);
CategoryRepository categoryRepository = new CategoryRepository(dbContext);
ProductController productController = new ProductController(productRepository, categoryRepository);
}
更新
我在测试构造函数中添加了上下文:
ApplicationDbContext dbContext;
public UnitTest1()
{
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "FakeDatabase")
.Options;
dbContext = new ApplicationDbContext(options);
}
和我的测试方法:
[Fact]
public void ProductsGetAll()
{
IProductRepository productRepository = new ProductRepository(dbContext);
ICategoryRepository categoryRepository = new CategoryRepository(dbContext);
ProductController productController = new ProductController(productRepository, categoryRepository);
var result = productController.List("Pizza");
var contentResult = result as ViewResult;
var final = contentResult != null;
Assert.False(final, "Shouldnt be null");
但现在我有一个错误:
Message: System.NullReferenceException : Object reference not set to an instance of an object.
【问题讨论】:
-
你到底在测试什么?如果是
ProductController,那么您应该模拟存储库以进行单元测试。另一方面,如果您正在进行集成测试,那么您必须指向一个实际的数据库,如果您希望它在本地机器上工作并构建服务器,您可能需要编写代码来生成一个临时数据库利用。另一种方法是在您的配置中保留连接字符串信息以指向本地位置并构建服务器数据库以进行测试。但是,您必须小心更改数据库的测试以及多次运行测试时这意味着什么。 -
通常您在单元测试中所做的是创建数据库的模拟,因为您不想在单元测试中测试用于集成测试的数据库。如果你模拟你的数据库和实体,你可以简单地使用一个 InitializeTest 方法来初始化你的测试上下文和模拟实体。我建议使用起订量
-
您是否考虑过使用内存数据库进行测试并在您的测试中使用它注入上下文?见docs.microsoft.com/en-us/ef/core/miscellaneous/testing/…
-
是否有任何选项可以为每种测试方法仅使用一个上下文?
-
单元测试不应该处理数据(例如
DbContext)。这是一个内部方面,与逻辑无关。应该模拟您的存储库,并且可以使用接口来完成。
标签: c# asp.net unit-testing asp.net-core