У меня есть класс регистратора, который должен вызываться из любого класса в моем решении, который решает что-то регистрировать. Я добавил интерфейс, поэтому применил одноэлементный шаблон и не использовал статический класс.
Моя реализация LogManager (синглтон): https://pastebin.com/NHKmbj9c
Я хотел написать простые модульные тесты, которые должны использовать локальные переменные, проверяя функциональность каждого метода ILogger, но как только мой первый модуль будет пройден, синглтон останется инициализированным в контексте, что приведет к сбою последующих модульных тестов (в то время как они пытаются инициализировать синглтон ...).
Модульный тест:
[TestClass]
public class LogManagerTests
{
[TestMethod]
public void Error_ExpectedErrorLevel_ShouldBe_Error()
{
// Arrange
var actualLevel = ErrorLevel.Warning;
const ErrorLevel expectedLevel = ErrorLevel.Error;
var iLogger = LogManager.GetInstance;
iLogger.Initialize((level, msg) => { actualLevel = level; }, null);
// Act
iLogger.Error(new Exception(), string.Empty);
// Assert
Assert.AreEqual(expectedLevel, actualLevel);
}
[TestMethod]
public void Debug_ExpectedErrorLevel_ShouldBe_Verbose()
{
// Arrange
var actualLevel = ErrorLevel.Warning;
const ErrorLevel expectedLevel = ErrorLevel.Verbose;
var iLogger = LogManager.GetInstance;
iLogger.Initialize(null, (level, msg, ex) => { actualLevel = level; });
// Act
iLogger.Debug(string.Empty);
// Assert
Assert.AreEqual(expectedLevel, actualLevel);
}
}
Еще одна идея - инициализировать LogManager как частную глобальную переменную в моем TestClass, но это может привести к условиям гонки, если Unit-тест выполняется асинхронно, поскольку несколько методов будут обращаться к одной и той же выходной переменной, которая может переопределять друг друга.
Можно ли каким-либо образом провести UnitTest синглтон?
Дизайн не позволяет мне провести рефакторинг LogManager и удалить из него одноэлементный шаблон.





Можно провести модульное тестирование синглтона, вам просто нужно подумать об этом по-другому. Не пытайтесь так сильно изменить свою методику, чтобы она соответствовала тесту. Подумайте о создании метода, который используется только для тестирования, LogManager.Uninitialize().
Вызывайте это после каждого теста в этой группе тестов, чтобы убедиться, что ваш синглтон вернулся в тестируемое состояние.
[TestCleanup()]
public void Cleanup()
{
LogManager.Uninitialize();
}
Это может быть не чисто, но я думаю, что время от времени можно писать метод диагностики. Это лучше, чем иметь плохое тестовое покрытие, когда вам нужно хорошее тестовое покрытие.
Может помочь: stackoverflow.com/questions/5897681/unit-testing-singletons Краткий ответ: не используйте синглтоны