2011-01-21 81 views
3

作爲一些測試的一部分,我期望臨時用一個將返回一組可預測的測試值的消息替換消息的內容。什麼是標準的Smalltalk-y方式來完成這類工作?是否有一些示例代碼供我查看?如何在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'. 
+0

你能舉一個例子嗎? – mathk 2011-01-22 21:00:17

+0

在運行時替換整個對象是*實用*和標準的smalltalk習慣用法。由一個委託幾乎所有的東西,它代理。 – 2011-01-26 13:58:12

+0

@Stephan你能提供一個這個成語的例子嗎?將置換對象採取原來的繼承層次結構中的位置(這樣我就可以,例如,更換爲O(100000)活動對象的祖先),或將我必須找到,然後再更換,每個單獨的對象? – blueberryfields 2011-01-26 14:24:50

回答

4

要對其他你可以替換一個消息:

a)以對應的方法(或多個),改變選擇器,它負責給定的消息發送。 b)使用代理來包裝所有感興趣的對象並攔截給定的消息,以便使用與原始方法不同的評估路徑。

2

我首先想到的是子類,並只覆蓋要返回測試值的特定消息。但是,您可能需要閱讀Ward wiki上的subclass to testsubclass to test anti-pattern條目。

要做到這一點,您需要將測試對象替換爲子類的實例,然後在完成後將其更改回測試中的原始類。

4

做到這一點的方法是使用MethodWrappers或相似。有一件事叫做「Objects as Methods」,它在Pharo和Squeak等一些Smalltalk方言中得到了支持(對其他方面不太確定)。這個想法是你可以使用任何對象作爲方法。所以,你可以這樣做:

MyClass methodDict at:#foo put:MyClassAsMethod new。

而且在MyClassMethod你必須實現#run:aSelector有:在參數:aReceiver

所以,當你這樣做:MyClass的新富。然後虛擬機會看到你有什麼不是一個CompiledMethod,而是另一個對象,然後它會發送消息#run:在:

如果我是你,我會下載pharo從這裏:https://gforge.inria.fr/frs/download.php/27524/Pharo-1.1.1-OneClickCogVM.zip

並且將調查包裝MethodWrappers及其所有類。

相關問題