2015-05-21 3 views
1

Я пишу интеграционные тесты для ServiceStack с базой данных в памяти, и я столкнулся с этим исключением: «System.IO.InvalidDataException ServiceStackHost.Instance уже установлен» при попытке запускайте несколько тестовых классов вместе, каждый из которых имеет свою собственную AppHostHttpListenerBase. Однако, если я запускал тестовые классы по одному, он запускался и проходил без проблем. Одна из причин наличия нескольких классов заключается в том, что я хочу протестировать AppHost с разными зарегистрированными службами/зависимостями, а также логически группировать свои тесты. Ниже приведен общий фрагмент моих тестов. Я бы хотел, чтобы каждый раз проводил все тесты.Тесты интеграции ServiceStack: ServiceStackHost.Instance уже установлен

public class TestClassOne : IDisposable 
{ 
    string _endPoint = "http://localhost:54321/"; 
    AppHostHttpListenerBase _appHost; 
    IDbConnectionFactory _dbConn = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider); 

    public TestClassOne() 
    { 
     _appHost = new UnitTestAppHost(_dbConn, ...){}; 
     _appHost.Init().Start(_endPoint); 
    } 

    [Fact] 
    public void Test() 
    { 
     ... 
     using(var db = _dbConn.Open()) 
     { 
      Assert.True(...); 
     } 
    } 

    public void Dispose() 
    { 
     _appHost.Dispose(); 
     _appHost = null; 
    }  
} 

public class TestClassTwo : IDisposable 
{ 
    string _endPoint = "http://localhost:54321/"; 
    AppHostHttpListenerBase _appHost; 
    IDbConnectionFactory _dbConn = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider); 

    public TestClassTwo() 
    { 
     _appHost = new UnitTestAppHost(...){}; 
     _appHost.Init().Start(_endPoint); 
    } 

    [Fact] 
    public void Test() 
    { 
     ... 
     using(var db = _dbConn.Open()) 
     { 
      Assert.True(...); 
     } 
    } 

    public void Dispose() 
    { 
     _appHost.Dispose(); 
     _appHost = null; 
    }  
} 

Я попытался запустить на другом домене приложения, но это не кажется, что я ищу, я думаю, потому что мне нужно сделать некоторые Утверждает на IDbConnection в текущем работает AppDomain (?), Если это имеет смысл. Любые предложения о том, как я должен это делать? Я использую xUnit и тестовый бегун Resharper.

+0

Я никогда не использовал его, так что это может быть немного случайным, но вы пытались изменить порт в конечной точке для разных тестов, чтобы узнать, не имеет значения? – forsvarir

+0

yup попробовал, прежде чем публиковать этот вопрос ... такое же исключение. – icube

+0

Это немного грязно .. и я снова предполагаю, но на основании ошибки статическое свойство экземпляра на ServiceHost все еще установлено после того, как вы вызвали Dispose на нем? Если да, попробовали ли вы сбросить свойство 'Instance'' ServiceHost' в null в 'Dispose'? Сетевой фильтр защищен, но вы можете * сделать это из своего класса UnitTestAppHost, который, как я предполагаю, получен из него. – forsvarir

ответ

0

Эта ошибка является результатом попыток запуска нескольких приложений AppHosts для каждого приложения. Каждый ServiceStack AppHost является одноэлементным и позволяет использовать только один AppHost для каждого приложения.

1

Я закончил это исправлением, создав класс AppHostSetupFixture с общедоступной статической переменной AppHost. Создайте метод [SetUp], который инициализирует ваш хост приложения и метод [TearDown], который его использует. Используйте AppHostSetupFixture.AppHost в ваших тестовых классах.

[SetUpFixture] 
public class AppHostSetupFixture 
{ 
    public static ServiceStackHost AppHost; 

    [SetUp] 
    public void Setup() 
    { 
     AppHost = new BasicAppHost(typeof(FeatureService).Assembly) 
     { 
      ConfigureContainer = container => 
      { 
       var l = new List<string>(); 
       l.Add(ConfigurationManager.ConnectionStrings["Redis"].ConnectionString); 
       container.Register<IRedisClientsManager>(c => new RedisManagerPool(l, new RedisPoolConfig() { MaxPoolSize = 40 })); 
      } 
     } 
     .Init(); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     AppHost.Dispose(); 
    } 
} 
+0

Может также использовать '[TestFixtureSetUp]/[TestFixtureTearDown]', поэтому он создается только один раз на испытательный прибор вместо каждого теста. – mythz

Смежные вопросы