2016-03-23 6 views
1

У меня есть тестовый класс, унаследованный от базового, который в основном вызывает метод контекста перед фактами, но XUnit звонит контекст один раз в самом деле:XUnit тест контекст для работы только один раз в классе

public class running_some_test : TestContext<ThingImTesting> 
public void Because() 
[Fact] 
public void it_should_do_something() 
[Fact] 
public void it_should_do_more() 
public void Context() 

Я знаю, Я мог бы использовать IClassFixture, но наследование TestContext обеспечивает проверку методами With() и Context() для переопределения вместе с типом SUT. Я также думаю, что IClassFixture является слишком общим, мой контекст очень специфичен для каждого критерия теста, а SetFixture больше похож на общий набор. У кого-нибудь есть аналогичная картина, за которой я мог бы следовать?

ответ

0

xunit создает экземпляр нового объекта из вашего тестового класса по факту. Это делается для того, чтобы дать каждому тесту свою собственную среду и облегчить параллелизм. Рекомендуемый способ совместного использования контекста между тестами в одном классе тестов - это интерфейс IClassFixture<T>.

Вы можете добавить метод Because() к вашему классу приборов, если вам нужен доступ к нему в ваших тестах. Мне кажется, что вы уже делаете что-то подобное, только вы делаете это с наследованием, а не композицией. Вы можете прочитать о том, как интерфейс работает здесь: https://xunit.github.io/docs/shared-context.html#class-fixture

Пример по ссылке:

public class DatabaseFixture : IDisposable 
{ 
    public DatabaseFixture() 
    { 
     Db = new SqlConnection("MyConnectionString"); 

     // ... initialize data in the test database ... 
    } 

    public void Dispose() 
    { 
     // ... clean up test data from the database ... 
    } 

    public SqlConnection Db { get; private set; } 
} 

public class MyDatabaseTests : IClassFixture<DatabaseFixture> 
{ 
    DatabaseFixture fixture; 

    public MyDatabaseTests(DatabaseFixture fixture) 
    { 
     this.fixture = fixture; 
    } 

    // ... write tests, using fixture.Db to get access to the SQL Server ... 
} 

XUnit впрыскивает класс арматуре с помощью вашего конструктора, так что вы можете делать такие вещи, как вы делаете их сейчас, только вы получаете доступ к членам прибора через введенный параметр, а не через ваш суперкласс.

+0

Эта реализация предполагает, что мне понадобится новый класс Fixture для каждого теста, который я пишу, чтобы сделать его конкретным для этого сценария. Я ищу что-то менее общее. – Grace

+0

Я в замешательстве, у вас нет создать новый класс, если это необходимо, и если это необходимо, как ваш нынешний подход избегает его? Что вы подразумеваете под менее общим? – kai

+0

Кроме того, чем больше я думаю об этом, почему вы хотите переместить «настроенный» код каждого теста в класс приборов? Похоже, что это сильно ухудшит читаемость ваших тестов, если каждый сценарий будет скрыт в другом классе. Вы должны держать свои тесты маленькими и целенаправленными. – kai