我使用 xUnit [理论] 编写测试。我的问题是我运行第一个测试并通过,而第二个测试抛出异常 ---- Microsoft.Data.Sqlite.SqliteException :SQLite 错误 19:'UNIQUE 约束失败:CONTRAHENT.ID'。当我单独运行每个测试时,在测试资源管理器中它们都通过了。所以我假设数据库在第二次运行之前没有被清除/处置。
public class TestDatabaseFixture
{
private const string ConnectionString = "DataSource=file::memory:?cache=shared";
private static readonly object _lock = new();
private static bool _databaseInitialized;
public TestDatabaseFixture()
{
lock (_lock)
{
if (!_databaseInitialized)
{
using (var context = CreateContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
}
_databaseInitialized = true;
}
}
}
public DbTrancheTest CreateContext(bool sensitiveDataLoggingEnabled = false)
=> new DbTrancheTest(
new DbContextOptionsBuilder<DbTranche>()
.EnableSensitiveDataLogging(sensitiveDataLoggingEnabled)
.UseSqlite(ConnectionString)
.Options);
}
测试课
public class TrancheServiceTest : IClassFixture<TestDatabaseFixture>
{
private TestDatabaseFixture Fixture { get; }
// private readonly ITestOutputHelper output;
public TrancheServiceTest(TestDatabaseFixture fixture)
{
Fixture = fixture;
}
[Theory]
[InlineData(TrancheStatus.created, true)] // passed
[InlineData(TrancheStatus.accepted, false)] // failed
[InlineData(TrancheStatus.chanaged, true)] // failed
[InlineData(TrancheStatus.waitforconf, false)] // failed
[InlineData(TrancheStatus.rejected, false)] //failed
public void Should_Set_Can_Edit_Flag_For_User(TrancheStatus status, bool result)
{
// Arrange
using var context = Fixture.CreateContext();
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var orderRepository = new TrancheOrderRepository(context);
var userRepo = new UserRepository(context);
var contrahentRepository = new ContrahentRepository(context);
contrahentRepository.Add(new CONTRAHENT { ID = 1, NAME = "Contrahent1" });
contrahentRepository.Save();
var trancheOrder = new TRANCHE_ORDER
{
ID = 1,
ISSUE_DATE = DateTime.Parse("2023-02-01"),
LAST_UPDATE = DateTime.Parse("2023-02-01"),
STATUS = (short)status,
VOLUME = 0,
USER = "",
};
orderRepository.Add(trancheOrder);
orderRepository.Save();
userRepo.Add(new USER { ID = 1, CAN_MODIFY = 1, DESCRIPTION = "Test user", FK_CONTRAHENT_ID = 1, NAME = "User1", USER_ID = 123 });
userRepo.Save();
var service = new TrancheService(contrahentRepository, orderRepository, userRepo);
DateTime dateFrom = DateTime.Parse("2023-01-01");
DateTime dateTo = DateTime.Parse("2023-12-01");
// Act
var trancheList = service.GetTrancheList(dateFrom, dateTo, 123, true);
// Assert
Assert.Collection(trancheList,
e => Assert.Equal(result, e.CanEdit));
}
}
就像@fildor所说,你每次都可以创建一个新的数据库。为此,您可以使用连接字符串,如下所示:
ConnectionString = "file:{0}?mode=memory";
并像这样更新你的代码:
public TestDatabaseFixture()
{
lock (_lock)
{
using (var context = CreateContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
}
}
}
}
public DbTrancheTest CreateContext(bool sensitiveDataLoggingEnabled = false)
=> new DbTrancheTest(
new DbContextOptionsBuilder<DbTranche>()
.EnableSensitiveDataLogging(sensitiveDataLoggingEnabled)
.UseSqlite(string.Format(ConnectionString, DateTime.Now.Ticks))
.Options);
我最终在每个单独的测试中创建上下文,如下所示。所有测试均通过。
using var context = new DbTrancheTest(
new DbContextOptionsBuilder<DbTranche>()
.EnableSensitiveDataLogging(false)
.UseSqlite(string.Format("DataSource=file::memory:?{0}", Guid.NewGuid().ToString()))
.Options);
context.Database.EnsureDeleted();
context.Database.EnsureCreated();