Подтвердить что ты не робот

Как вы издеваетесь над Запечатанным классом?

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

Итак, что лучше всего вы издеваетесь над закрытыми классами?

Ответы Java более чем приветствуются. На самом деле, я ожидал, что сообщество Java уже справляется с этим и может предложить многое.

Но вот некоторые из мнений .NET:

4b9b3361

Ответ 1

Мое общее правило состоит в том, что объекты, которые мне нужны для макета, должны иметь общий интерфейс. Я думаю, что это правильный дизайн и делает тесты намного проще (и обычно это то, что вы получаете, если вы делаете TDD). Подробнее об этом можно прочитать в блоге Google Testing последнее сообщение (см. Пункт 9).

Кроме того, я работал в основном на Java за последние 4 года, и могу сказать, что могу рассчитывать, с одной стороны, количество раз, когда я создал окончательный (запечатанный) класс. Другое правило: у меня всегда есть веская причина, чтобы запечатать класс, а не запечатывать его по умолчанию.

Ответ 2

Для .NET вы можете использовать что-то вроде TypeMock, которое использует API профилирования и позволяет подключаться к вызовам почти ко всему.

Ответ 3

Я считаю, что Moles из Microsoft Research позволяет это сделать. На странице Moles:

Моли могут использоваться для обхода любых .NET. метод, в том числе не виртуальный/статический методы в закрытых типах.

UPDATE: появилась новая фреймворк под названием "Подделки" в предстоящем выпуске VS 11, который предназначен для замены Moles:

Fakes Framework в Visual Studio 11 является следующим поколением Moles и Stubs и в конечном итоге заменит его. Подделки отличаются от Moles, однако, поэтому переход от Moles to Fakes потребует внесения некоторых изменений в ваш код. Руководство по этой миграции будет доступно позднее.

Требования: Visual Studio 11 Ultimate,.NET 4.5

Ответ 4

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

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

Ответ 5

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

Это также облегчает переход моих зависимостей в долгосрочной перспективе.

Ответ 6

Есть ли способ реализовать герметичный класс из интерфейса... и вместо этого имитирует интерфейс?

Что-то во мне чувствует, что в первую очередь ошибочно запечатаны классы, но это только я:)

Ответ 7

Я обычно беру путь создания интерфейса и класса адаптера/прокси, чтобы облегчить насмешку закрытого типа. Тем не менее, я также экспериментировал с пропуском создания интерфейса и созданием прокси-типа, не запечатанного виртуальными методами. Это сработало хорошо, когда прокси-сервер действительно является естественным базовым классом, который инкапсулирует и использует часть закрытого класса.

При работе с кодом, который требовал этой адаптации, я устал от выполнения тех же действий для создания интерфейса и типа прокси, поэтому я реализовал библиотеку для автоматизации задачи.

Код несколько более сложный, чем образец, указанный в статье, которую вы ссылаетесь, поскольку она создает сборку (вместо исходного кода), позволяет генерировать код для любого типа и не требует такой конфигурации.

Для получения дополнительной информации см. эту страницу.

Ответ 8

Совершенно разумно издеваться над закрытым классом, потому что многие каркасные классы запечатаны.

В моем случае я пытаюсь высмеять класс .Net MessageQueue, чтобы я мог TDD использовать мою грациозную логику обработки исключений.

Если у кого-то есть идеи о том, как преодолеть ошибку Moq в отношении "Недопустимая настройка для неперехваченного члена", сообщите мне.

код:

    [TestMethod]
    public void Test()
    {
        Queue<Message> messages = new Queue<Message>();
        Action<Message> sendDelegate = msg => messages.Enqueue(msg);
        Func<TimeSpan, MessageQueueTransaction, Message> receiveDelegate =
            (v1, v2) =>
            {
                throw new Exception("Test Exception to simulate a failed queue read.");
            };

        MessageQueue mockQueue = QueueMonitorHelper.MockQueue(sendDelegate, receiveDelegate).Object;
    }
    public static Mock<MessageQueue> MockQueue
                (Action<Message> sendDelegate, Func<TimeSpan, MessageQueueTransaction, Message> receiveDelegate)
    {
        Mock<MessageQueue> mockQueue = new Mock<MessageQueue>(MockBehavior.Strict);

        Expression<Action<MessageQueue>> sendMock = (msmq) => msmq.Send(It.IsAny<Message>()); //message => messages.Enqueue(message);
        mockQueue.Setup(sendMock).Callback<Message>(sendDelegate);

        Expression<Func<MessageQueue, Message>> receiveMock = (msmq) => msmq.Receive(It.IsAny<TimeSpan>(), It.IsAny<MessageQueueTransaction>());
        mockQueue.Setup(receiveMock).Returns<TimeSpan, MessageQueueTransaction>(receiveDelegate);

        return mockQueue;
    }

Ответ 9

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

  • Создать экземпляр закрытого класса без вызова конструктора.
  • System.Runtime.Serialization.FormatterServices.GetUninitializedObject(instanceType);

  • Присвоить значения вашим свойствам/полям с помощью отражения

  • YourObject.GetType(). GetProperty ( "PropertyName" ). SetValue (dto, newValue, null);
  • YourObject.GetType(). GetField ( "FieldName" ). SetValue (dto, newValue);

Ответ 10

Несмотря на то, что в настоящее время он доступен только в бета-версии, я думаю, что его стоит иметь в виду shim функцию нового Faces framework (часть Visual Studio 11 бета-версия).

ШИМ-типы предоставляют механизм для обхода любого метода .NET определенному делегату. Типы прошивок генерируются кодом генератором Fakes, и они используют делегаты, которые мы называем shim-типами, чтобы указать новые реализации методов. Под капотом типы прокладок используют обратные вызовы, которые были введены во время выполнения в методах MSIL.

Лично я искал использование этого, чтобы издеваться над методами на закрытых классах фреймворка, таких как DrawingContext.