Вопрос Программисту - как заменить этот синглтон на его мок?
Вопрос специально к юзеру Программист.
Ты утверждаешь, что сделав сеттер точки доступа к синглтону internal, можно сделать этот синглтон mockable.
Моя фраза:
Замена модификатора сеттера на internal никаким образом не поможет синглтон сделать mockable.
Твой ответ:
Ошибаешься.
Ну и дальше пошла от тебя какая-то пурга, мерянье пиписьками:
В отличае от тебя, я...
...привести рабочий код синглтона ты не смог.
Сначала по поводу "привести рабочий код синглтона". Да *б твою ж мать! Ругаться грязно хочется. Меня кто-то просил рабочий код синглтона приводить? Ты вообще понимаешь разницу между схематичным наброском и рабочим кодом? Ты на StackOverflow тоже ко всем вопросам и ответам комменты такие пишешь, что у них там код нерабочий, потому что половины не хватает? Я же написал - это каракули, чтобы продемонстрировать, сколько кривых зависимостей может быть.
А то получается такой диалог:
dymanoid: Вот схема ДТП. Объясните мне, как вообще этот чувак на зелёной тачке мог сюда повернуть?
Программист: Да у тебя зелёная тачка вообще никуда не поедет, ты там колёса не нарисовал.
dymanoid: Да при чём тут колёса? Я вообще на автозаводе работаю и всё могу про колёса рассказать. Ты лучше посмотри на взаимное положение тачек на картинке!
Программист: Всё понятно. Рабочую картинку авто ты нарисовать не смог. Не знаю, чего ты там про колёса можешь объяснить. В отличие от тебя, я стопицот видов колёс уже нарисовал и точно знаю, где на них размерность покрышек находится.
Я могу привести тебе как минимум 7 разновидностей рабочего кода синглтонов и рассказать про все их достоинства, недостатки, быстродействие и до фига всего ещё. Но не в этой теме.
А в этой теме ты мне, пожалуйста, покажи, как ты с internal сеттером к точке доступа к синглтону собираешься его заменить на мок в тесте. Ниже вот тебе рабочий код синглтона, чтобы не придирался. Код абсолютно от балды, выдуманный.
Предположим, я тест хочу на CI-серваке запустить, поэтому там без моков это всё не будет работать. Во-первых, логин не тот, во вторых, предположим, к базе нет доступа.
(Ну и, конечно, это абсолютно дурацкое решение делать сеттер в синглтоне internal - открываем ворота для всех подряд в сборке, мол, меняйте объект, когда хотите. Уже предвкушаю ответы: "да никто не будет этого делать", "надо в комментариях написать, что только в тестах менять можно" - прям в каком-то идеальном мире живёшь, или не работал ни разу в командах по 200 человек.)
class UserRepository { private static readonly Lazy<UserRepository> instance = new Lazy<UserRepository>(); public static UserRepository Instance => instance.Value; private UserRepository() { } public string CurrentUser => "get-Windows-login"; /* Здесь сложный код получения юзера */ public object GetUserToken(string userName) => null; /* Здесь сложный код получения токена из имени */ } class ConfigRepository { private static readonly Lazy<ConfigRepository> instance = new Lazy<ConfigRepository>(); public static ConfigRepository Instance => instance.Value; private readonly object userToken; private ConfigRepository() { userToken = UserRepository.Instance.GetUserToken(UserRepository.Instance.CurrentUser); } private IEnumerable GetConfigItems() { using (var conn = new SqlConnection(Properties.Resources.ConnectionString)) { using (var dbContext = new MyDbContext(conn, contextOwnsConnection: true)) { return dbContext.ConfigItems.Where(c => c.UserToken == userToken).ToList(); } } } public int HowManyConfigItems(DateTime oldest) { return GetConfigItems().Count(c => c.CreationDate >= oldest); } } [TestClass] public class MyTestClass { [TestMethod] public void MyTestMethod() { // ну и как? var configItemsCount = ConfigRepository.Instance.HowManyConfigItems(DateTime.Now); Assert.AreEqual(42, configItemsCount); } }