Тесты xUnit не пройдены с общими статическими данными - PullRequest
0 голосов
/ 01 декабря 2018

У меня есть несколько модульных тестов, которые используют некоторый статический класс, например:

public static class Utility
{
    private static Data data;

    public static void Init(Data data)
    {
        this.data = data;
    }

    public static void Process()
    {
        // Some actions that changes this.data (not reference, just inner Values)
    }
}

public class Data
{
    public List<string> Values { get; set; }

    public void Add(string value)
    {
        Values.Add(value);
    }
}

Каждый модульный тест инициализирует экземпляр данных и передает его в утилиту:

[Fact]
public void UnitTest1()
{
    var data = new Data();
    data.Add("val1");
    Utility.Init(data);

    Utility.Process();

    // check changed data instance
}

[Fact]
public void UnitTest2()
{
    var data = new Data();
    data.Add("another_val1");
    data.Add("another_val2");
    Utility.Init(data);

    Utility.Process();

    // check changed data instance
}

Если я запускаюКаждый тест в отдельности, то нет проблем - нет неудачных тестов.Но если я запускаю тесты последовательно, то один из модульных тестов не пройден, потому что Utility.data содержит экземпляр предыдущего теста (на короткое время), несмотря на вызов Utility.Init.Если я запускаю тесты через командную строку (тесты выполняются очень быстро), большая часть тестов, скорее всего, не будет выполнена по той же причине.Как я могу решить эту проблему?

1 Ответ

0 голосов
/ 01 декабря 2018

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

public class Utility
{
    private Data data;

    public Utility(Data data) {
        this.data = data;
    }

    public void Process() {
        // Some actions that changes this.data (not reference, just inner Values)
    }
}

Какой пример теста будет выглядеть

[Fact]
public void UnitTest1() {
    //Arrrange
    var data = new Data();
    data.Add("val1");
    var subject = new Utility(data);

    //Act
    subject.Process();

    //Assert
    // check changed data instance
}

Я подозреваю, что проблема initil была XY проблема и что Утилита также используется в качестве статической зависимости в производственном процессе, что является запахом кода.

В этом случае абстрагируйте класс статической утилиты

public interface IUtility {
    void Process(Data data);
}

и выполните рефакторинг реализации

public class Utility : IUtility {

    public void Process(Data data) {
        // Some actions that changes this.data (not reference, just inner Values)
    }
}

Что приведет к тому, что тест будет выглядеть как

[Fact]
public void UnitTest1() {
    //Arrrange
    var data = new Data();
    data.Add("val1");
    var subject = new Utility();

    //Act
    subject.Process(data);

    //Assert
    // check changed data instance
}

[Fact]
public void UnitTest2() {
    var data = new Data();
    data.Add("another_val1");
    data.Add("another_val2");
    var subject = new Utility();

    //Act
    subject.Process(data);

    //Assert
    // check changed data instance
}

IUtility будет вставлен в зависимые классы по мере необходимости, что сделает полученный код более SOLID.

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