我正在为单元测试创建SQLite内存数据库:
var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
try
{
var options = new DbContextOptionsBuilder<BloggingContext>()
.UseSqlite(connection)
.Options;
// Create the schema in the database
using (var context = new BloggingContext(options))
{
context.Database.EnsureCreated();
}
// Run the test against one instance of the context
using (var context = new BloggingContext(options))
{
var service = new BlogService(context);
service.Add("http://sample.com");
}
// Use a separate instance of the context to verify correct data was saved to database
using (var context = new BloggingContext(options))
{
Assert.AreEqual(1, context.Blogs.Count());
Assert.AreEqual("http://sample.com", context.Blogs.Single().Url);
}
}
**上下文.数据库.EnsureCreated();*失败,出现异常: 消息:Microsoft数据库异常:SQLite错误1:'接近“最大值”:语法错误'. *
有github issue说:* 这里的问题是varchar(max)是SqlServer特定的类型。搭建不应将其添加为关系类型,因为它会传递给其他提供程序中的迁移,这很容易在迁移时生成无效的sql。*
但是如果我的数据库包含许多varchar(max)列,我如何使用SQLite in Memory进行单元测试呢?
2条答案
按热度按时间vjhs03f71#
我没有找到一个直接的解决方案,但已经开始使用配置文件的变通方案。你没有指出,如果你使用的EF配置,所以原谅基本的,如果不需要。
在DbContext中放置以下内容:
现在创建一个静态类,如下所示,它将接受你的属性并处理配置。
为要配置的每个实体创建Configuration类
保持HasColumnType(“text”)不加注解以进行测试,然后在添加迁移时注解该行并取消注解HasColumnType(“varchar(max)”)。
这是一个痛苦,你需要记住这样做,但它是一个相当简单的变通办法。
qxsslcnc2#
我的解决方案:在AppDbContext中定义一个标志为true(在我的例子中,意味着这是针对我的SqlServer的)。每当AppDbContext从Test项目初始化时,将该标志设置为false(因为对于测试,我们使用SqlLite)。
最后,在OnModelCreating中,为那些具有nvarchar(max)的实体检查标志,如果为false(意味着我正在运行测试),则将那些nvarchar(max)属性的ColumnTypes设置为Text。
在AppDbContext中:
在AppDbContext.OnModelCreating中,为具有这些nvarchar属性的实体执行以下操作,以将类型从nvarchar(max)更改为text:
最后,在您的测试项目初始化中,将标志设置为false以更改类型,这样它就不会失败。