2

我正在使用內存數據庫(使用ServiceStack.OrmLite.Sqlite.Windows)在基於servicestack的web api中進行單元測試。我想測試依賴於通過內存數據庫的存儲過程,我已經通過鏈接Servicestack Ormlite SqlServerProviderTests,我使用的測試是如下的單元測試類了服務端點,使用SqLite將存儲過程添加到內存數據庫中

 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執行此操作,它工作正常。但是當我試圖對與內部存儲器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>(); 

        }    
       } 

爲什麼我們都面臨這個例外是有任何其他方式在內部存儲器DB的SQLite添加和運行存儲過程?

回答

3

錯誤是因爲您嘗試使用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(); 
相關問題