Контейнер Unity теряет регистрации при использовании в тестах - PullRequest
2 голосов
/ 11 января 2012

Я работаю с командой, у которой были проблемы со случайными неудачными тестами.Неудачные тесты, по-видимому, только провалились на сервере сборки (TFS).Но, когда я исследовал проблему, я смог заставить их также выйти из строя на моей локальной машине.

Кажется, я решил проблему, но мне нужно подтверждение моей теории о неудачных тестах.

Один из тестов, который не прошел, имел этот метод TestInitialize:

    [TestInitialize]
    public void TestInit()
    {
        Mock<ILog> loqMock = new Mock<ILog>();
        Depend.RegisterInstance(loqMock.Object);
    }

Класс Depend является статической оболочкой вокруг контейнера Unity.Внутри него есть локальная ссылка на контейнер Unity.Некоторые тесты в этом приборе сбои кажутся случайными.

Моя теория состоит в том, что переменная logMock разыменовывается, поскольку нет ссылки ни на этот класс, ни на класс Depend после возврата из метода Initialize.

Я «исправил» проблему, изменив код следующим образом:

    private Mock<ILog> loqMock;

    [TestInitialize]
    public void TestInit()
    {
        loqMock = new Mock<ILog>();
        Depend.RegisterInstance(loqMock.Object);
    }

Теперь на переменную logMock ссылаются до тех пор, пока существует тестовое исправление.Я не могу заставить его потерпеть неудачу, как я мог бы с другой установкой.

PS: я знаю, что это использование контейнера IOC - действительно плохая идея и что это должно быть изменено, но проект яконсультирование, у меня нет ресурсов для внесения изменений, и я ничего не могу с этим поделать.

1 Ответ

1 голос
/ 11 января 2012

Jand187, Вы на 100% правы, что объект loqMock собирается сборщиком мусора. Вы регистрируете только тот объект, который создается вашим Mock, который не содержит ссылку на сам объект Mock.

Один из способов убедиться в этом - использовать установку, в которой иногда происходит сбой, и перед выполнением строки, в которой произошел сбой, выполнить GC.Collect (). После вызова GC он должен каждый раз выходить из строя.

Если вы хотите, чтобы объект, который определен и инициализирован в методе TestInit () вашего модульного теста, продолжал существовать в течение всего этого времени, вы должны будете убедиться, что хотя бы одна ссылка на него находится в «некотором» объекте, будет иметь жизненный цикл, равный или дольше, чем продолжительность теста - в этом случае ваше «исправление» (цитирование цитаты) абсолютно правильно.

Если вас интересует, почему и как, вот ссылка на очень полезную рецензию MS, относительно глубоко охватывающую сборку мусора: http://msdn.microsoft.com/en-us/library/ee787088.aspx

Удачи!

Адам

...