gpt4 book ai didi

unit-testing - 使用 Sqlite 将存储过程添加到内存数据库

转载 作者:行者123 更新时间:2023-12-04 04:48:33 24 4
gpt4 key购买 nike

我正在使用内存数据库(使用 ServiceStack.OrmLite.Sqlite.Windows)在基于 servicestack 的 web api 中进行单元测试。我想通过我浏览过链接 Servicestack Ormlite SqlServerProviderTests 的内存数据库测试依赖于存储过程的服务端点,我用于测试的单元测试类如下,

        using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using NUnit.Framework;
using ServiceStack.Text;
using ServiceStack.Configuration;
using ServiceStack.Data;

namespace ServiceStack.OrmLite.Tests
{
public class DummyTable
{
public int Id { get; set; }
public string Name { get; set; }
}

[TestFixture]
public class SqlServerProviderTests
{
private IDbConnection db;
protected readonly ServiceStackHost appHost;

public SqlServerProviderTests()
{
appHost = TestHelper.SetUp(appHost).Init();
db = appHost.Container.Resolve<IDbConnectionFactory>().OpenDbConnection("inventoryDb");

if (bool.Parse(System.Configuration.ConfigurationManager.AppSettings["IsMock"]))
TestHelper.CreateInMemoryDB(appHost);
}

[TestFixtureTearDown]
public void TearDown()
{
db.Dispose();
}

[Test]
public void Can_SqlColumn_StoredProc_returning_Column()
{
var sql = @"CREATE PROCEDURE dbo.DummyColumn
@Times integer
AS
BEGIN
SET NOCOUNT ON;

CREATE TABLE #Temp
(
Id integer NOT NULL,
);

declare @i int
set @i=1
WHILE @i < @Times
BEGIN
INSERT INTO #Temp (Id) VALUES (@i)
SET @i = @i + 1
END
SELECT * FROM #Temp;

DROP TABLE #Temp;
END;";
db.ExecuteSql("IF OBJECT_ID('DummyColumn') IS NOT NULL DROP PROC DummyColumn");
db.ExecuteSql(sql);

var expected = 0;
10.Times(i => expected += i);

var results = db.SqlColumn<int>("EXEC DummyColumn @Times", new { Times = 10 });
results.PrintDump();
Assert.That(results.Sum(), Is.EqualTo(expected));

results = db.SqlColumn<int>("EXEC DummyColumn 10");
Assert.That(results.Sum(), Is.EqualTo(expected));

results = db.SqlColumn<int>("EXEC DummyColumn @Times", new Dictionary<string, object> { { "Times", 10 } });
Assert.That(results.Sum(), Is.EqualTo(expected));
}
}
}

当我尝试通过 Live-DB 执行此操作时,它运行良好。但是当我尝试使用内存数据库时,出现如下异常,
        System.Data.SQLite.SQLiteException : SQL logic error or missing database near "IF": syntax error

在代码行附近,
        db.ExecuteSql("IF OBJECT_ID('DummyColumn') IS NOT NULL DROP PROC DummyColumn");

我评论了上面的行并执行了测试用例,但仍然出现如下异常,
        System.Data.SQLite.SQLiteException : SQL logic error or missing database near "IF": syntax error

对于代码行,
        db.ExecuteSql(sql);

In-Memory DB Created 如下,它在剩余情况下工作正常。
        public static void CreateInMemoryDB(ServiceStackHost appHost)
{
using (var db = appHost.Container.Resolve<IDbConnectionFactory>().OpenDbConnection("ConnectionString"))
{
db.DropAndCreateTable<DummyData>();
TestDataReader<TableList>("Reservation.json", "InMemoryInput").Reservation.ForEach(x => db.Insert(x));

db.DropAndCreateTable<DummyTable>();

}
}

为什么我们面临这个异常有没有其他方法可以使用 Sqlite 在内存数据库中添加和运行存储过程?

最佳答案

该错误是因为您尝试使用 TSQL 针对 Sqlite 的内存版本运行特定于 SQL Server 的查询。 - 即一个完全不同的、可嵌入的数据库。顾名思义SqlServerProviderTests仅适用于 SQL Server,我很困惑您为什么要尝试针对 Sqlite 运行它?

SQLite 不支持存储过程、TSQL 等,因此尝试执行 SQL Server TSQL 语句总是会导致错误。你唯一能做的就是用 custom Exec Filter 伪造它,您可以在其中捕获异常并返回您喜欢的任何自定义结果,例如:

public class MockStoredProcExecFilter : OrmLiteExecFilter
{
public override T Exec<T>(IDbConnection dbConn, Func<IDbCommand, T> filter)
{
try
{
return base.Exec(dbConn, filter);
}
catch (Exception ex)
{
if (dbConn.GetLastSql() == "exec sp_name @firstName, @age")
return (T)(object)new Person { FirstName = "Mocked" };
throw;
}
}
}

OrmLiteConfig.ExecFilter = new MockStoredProcExecFilter();

关于unit-testing - 使用 Sqlite 将存储过程添加到内存数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37944392/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com