Как программно заменить тело сообщения в Smalltalk? - PullRequest
3 голосов
/ 21 января 2011

В рамках некоторого тестирования я временно заменяю содержимое сообщения тем, которое будет возвращать предсказуемый набор тестовых значений.Что является стандартным способом Smalltalk-й для выполнения этой работы?Есть ли какой-нибудь пример кода для просмотра?

Некоторые пояснения:

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

Вот некоторый псевдокод для того, что я хочу написать:

replaceMessage: 'fibonacci' 
       onClass: 'funFunctions' 
          with: 'returnsPredictableNumbersWithoutCalculatingThem'.

self runTestSet1.

restoreMessage: 'fibonacci' 
       onClass: 'funFunctions'.

self runFollowUpSet1. "Depends on state set by Set1"

replaceMessage: 'fibonacci' 
       onClass: 'funFunctions' 
          with: 'returnsPredictableNumbersWithoutCalculatingThemPart2'.

self runFollowUpSet2. "Depends on state set by followupset1"

restoreMessage: 'fibonacci' 
       onClass: 'funFunctions'.

Ответы [ 4 ]

4 голосов
/ 24 января 2011

Чтобы заменить одно сообщение другим, вы можете:

a) в соответствующем методе (ах) измените селектор, отвечающий за отправку данного сообщения.

b) использовать прокси, чтобы обернуть все интересующие объекты и перехватить данное сообщение, чтобы использовать другой путь оценки, чем в оригинальном методе.

4 голосов
/ 23 января 2011

Способ сделать это - использовать MethodWrappers или аналогичный. Есть одна вещь, называемая «Объекты как методы», которая поддерживается в некоторых диалектах Smalltalk, таких как Pharo и Squeak (не уверен в других). Идея в том, что вы можете использовать любой объект в качестве метода. Итак, вы можете сделать это:

Метод MyClassDict по адресу: #foo put: MyClassAsMethod new.

И в MyClassMethod вы должны реализовать #run: aSelector с аргументами в: aReceiver

Итак, когда вы делаете: MyClass new foo. Затем виртуальная машина увидит, что то, что у вас есть, это НЕ CompiledMethod, а другой объект, и затем отправит этому объекту сообщение

На вашем месте я бы скачал pharo отсюда: https://gforge.inria.fr/frs/download.php/27524/Pharo-1.1.1-OneClickCogVM.zip

и исследует пакет MethodWrappers и все его классы.

3 голосов
/ 22 января 2011

Может быть MethodWrappers - бумага ECOOP Упаковщики на помощь

2 голосов
/ 21 января 2011

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

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

...