c# - asp.net core 数据库集成测试
问题描述
我正在尝试在 asp.netcore 项目中设置数据库的集成测试。我正在使用代码优先的方法来创建数据库。
对于使用 nudget 包 XUnit、FluentAssertions 和 NUnitestApadter3 的测试 iam。当我第一次运行测试时,测试通过了。
[Collection("Integration test collection")]
public class BookServiceTest : IntegrationTestBase
{
[Fact]
public void CanCreateUser()
{
using (var context = GivenBPDContext())
{
var Book = new BookService(context);
Data.Database.Entities.Book book = Book.AddNewBook("test");
context.SaveChanges();
book.Id.Should().NotBe(0);
book.Name.Should().Be("test");
}
}
}
public class IntegrationTestBase
{
protected static BPDContext GivenBPDContext()
{
var context = new BPDContext(new DbContextOptionsBuilder().Options);
return context;
}
// i tried dropping the database here and it do not work
}
一个非常基本的逻辑测试
public class BookService
{
private BPDContext _context;
public BookService(BPDContext context)
{
_context = context;
}
public Book AddNewBook(string name)
{
var book = _context.Books
.FirstOrDefault(x => x.Name == name);
if (book == null)
{
book = _context.Books.Add(new Data.Database.Entities.Book
{
Name = name,
}).Entity;
}
return book;
}
}
我第二次运行测试并更改正在测试的值时失败。我需要一种在每次测试后删除数据库然后运行迁移以使数据库升级到正确版本的方法。
下面是我如何设置数据库。启动.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<IBPDRepository, BPDRepository>();
services.AddDbContext<BPDContext>();
}
public class BPDContext:DbContext
{
public DbSet<Entities.Book> Books { get; set; }
public DbSet<Entities.User> User { get; set; }
public DbSet<Entities.Reviewer> Reviewer { get; set; }
public BPDContext(DbContextOptions options):base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//maybe put something in if its in testing mode
optionsBuilder.UseSqlServer("Server = (localdb)\\mssqllocaldb;Database = BookProjectDatabase;Trusted_Connection = True; ", options => options.MaxBatchSize(30));
optionsBuilder.EnableSensitiveDataLogging();
}
}
总之,我需要在每次测试运行之前删除数据库,然后使用迁移更新数据库,最后执行单元。
解决方案
看看重生。避免迁移的另一个选择是执行数据库快照/恢复。最后,您可以在每次测试之前启动一个新的TransactionScope,然后Dispose()
在事务之后调用它的方法而不调用它的Complete()
方法。这将中止事务并将数据库回滚到运行测试之前的状态。
删除数据库有点笨拙,可能会增加运行测试所需的时间。
推荐阅读
- java - 执行 list.set(1000, someValue) 时是否增加 arrayList?
- xml - 我们可以将 Amazonesia Blogger 模板转换为响应式模板吗
- javascript - 使用javascript检查输入上的增量箭头的值
- jquery - jQuery计算json数据的总长度不正确
- ansible - 如何使用 ansible 从 yaml 文件中获取自定义列表?
- angular - 角度显示这种类型的错误我如何解决这个问题?
- json - 如何按条件选择最大值然后与其他值进行比较?
- kotlin - Kotlin:防止混淆相同类型的参数
- wordpress - 在 WordPress 中按产品按钮过滤产品
- javascript - 如何根据javascript中的滚动位置动态更改div的高度?