2

서비스 스택 기반 웹 API에서 단위 테스트를 위해 In-Memory 데이터베이스 (ServiceStack.OrmLite.Sqlite.Windows 사용)를 사용하고 있습니다. 나는SqLite를 사용하여 In-Memory DB에 저장 프로 시저 추가

 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)); 
       } 
      } 
     } 

때, 내가 링크 Servicestack Ormlite SqlServerProviderTests, 나는 다음과 같다 시험에 사용하고있는 단위 테스트 클래스를 통해 갈되는 인 - 메모리 데이터베이스를 통해 저장 프로 시저에 따라 서비스 엔드 포인트를 테스트 할 나는 이것을 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"); 

은 내가 위의 줄을 주석하고 테스트 케이스를 실행하지만 여전히 나는 예외를 얻고있다 AS는 코드 라인

 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를 사용하여 인 - 메모리 DB에 저장 프로 시저를 추가하고 실행하는 다른 방법이 있습니까?

답변

3

메모리의 버전이 Sqlite 인 TSQL을 사용하여 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();