mJa*_*Jay 5 c# sqlite unit-testing entity-framework asp.net-core
我正在测试我的服务层,其中包含使用 SQLite 数据库提供程序对存储库的一些调用。我的测试类是按照如下介绍写的:https : //docs.microsoft.com/en-us/ef/core/miscellaneous/testing/sqlite
对于此测试用例中写入数据库的实体,在数据库上生成 Guid:
entity.Property(e => e.Guid).HasDefaultValueSql("newid()");
Run Code Online (Sandbox Code Playgroud)
现在,当尝试添加一个新实体(没有明确设置 Guid)时,我得到以下异常:
SQLite Error 1: 'unknown function: newid()'.
Run Code Online (Sandbox Code Playgroud)
有没有办法解决这个问题? 似乎根本不支持此功能。由于我正在使用的数据库很旧,我害怕找到更多这样的地方可能不起作用。
我的希望是使用 SQLite 获得比使用 InMemoryDatabase 提供程序更好的单元测试,后者并不真正适合测试“关系数据库功能”。但是如果这个问题不能解决,我就卡住了,可能需要坚持集成测试(至少对于我服务的数据访问部分)
如果您引用 Microsoft.Data.Sqlite,您可以在 c# 中创建一个自定义函数来执行此操作
例如:
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" };
var connection = new SqliteConnection(connectionStringBuilder.ToString());
connection.CreateFunction("newid", () => Guid.NewGuid());
Run Code Online (Sandbox Code Playgroud)
有关 System.Data.SQLite 和 Microsoft.Data.Sqlite 之间的比较,请参见此处
我猜您对于 MySql 或任何其他数据库都会遇到这个问题,uuid()因为newid(). 我的第一个建议是在应用程序端生成 GUID 并将其传递给数据库,但您可能已经想到了这一点但不能。作为解决方法,您可以创建如下扩展方法:
public static class Extensions
{
private static readonly Dictionary<Type, string> NewIdDictionary = new Dictionary<Type, string>
{
{ typeof(SqlServerOptionsExtension), "newid()" }
};
public static PropertyBuilder<TProperty> HasDefaultValueForSql<TProperty>(this PropertyBuilder<TProperty> propertyBuilder,
DbContextOptions contextOptions)
{
var result = contextOptions.Extensions.Select(extension =>
{
if (!(extension is RelationalOptionsExtension item)) return string.Empty;
return NewIdDictionary.TryGetValue(item.GetType(), out var sql) ? sql : string.Empty;
}).SingleOrDefault(s => !string.IsNullOrEmpty(s));
return propertyBuilder.HasDefaultValueSql(result);
}
}
Run Code Online (Sandbox Code Playgroud)
尽管没有 SQLite 的等效项,但在将 null 传递给.HasDefaultValueSql. 然后您可以根据需要添加其他扩展类型。
| 归档时间: |
|
| 查看次数: |
1341 次 |
| 最近记录: |