2013-07-11 42 views
1

我一直在研究如何處理在更快的服務器版本上開始失敗的繼承flexunit測試。在單元測試開始運行之前,MyMockService沒有準備好。我們正在使用FlexUnit和Mockolate。使用異步FlexUnit測試的錯誤或預期行爲?

<failure 
    message="A proxy for com.something.somemock.service::MyMockService has not been prepared yet" 
    type="com.something.somemock.MyAsyncTest">ArgumentError: A proxy for com.something.somemock.service::MyMockService has not been prepared yet. 
    //... (lots removed here) 
</failure> 

通用進口:

import flash.events.Event; 
import flexunit.framework.Assert; 
import mockolate.nice; 
import mockolate.prepare; 
import mockolate.stub; 
import mockolate.verify; 
import org.flexunit.async.Async; 
import flash.utils.Timer; 
import flash.events.TimerEvent; 

下面的代碼的存根。 (我認爲)重要的部分在那裏,所以你可以獲得要點。

public class MyAsyncTest 
{ 

    [Before(async)] 
    public function prepareMockObjects():void 
    { 
     Async.proceedOnEvent(this, prepare(MyMockService), Event.COMPLETE); 
    } 

    [Test(async)] 
    public function testExecute():void 
    { 

     var service:MyMockService = nice(MyMockService); 
     verify(service).method("runSomething").args(ArgumentBuilder).once(); 

    } 
} 

做了很多工作,改變超時和增加睡眠的方法(在對抗錯誤都沒用)後,我已經介紹了第二次檢查僅包含一個延遲FlexUnit測試類。我下令進行測試,並發現我的測試現在每次都通過。 (這很好)我真的很討厭把測試放在一邊,這樣我就可以得到準備完成所需的三秒延遲。

下面是視覺效果的代碼存根:

public class MyAsyncTest 
{ 
    protected function makeMeSleep(howLongMs:int):void 
    { 
     //timer code to sleep 
    } 

    [Before(async)] 
    public function prepareMockObjects():void 
    { 
     Async.proceedOnEvent(this, prepare(MyMockService), Event.COMPLETE); 
    } 

    [Test(async, order=1)] 
    public function delayTheNextTest():void 
    { 
     var hasPaused:Boolean = makeMeSleep(3000); 
     Assert.assertTrue("This is a silly delay to allow the service to prepare", true); 
    } 

    [Test(async, order=2)] 
    public function testExecute():void 
    { 
     var service:MyMockService = nice(MyMockService); 
     verify(service).method("runSomething").args(ArgumentBuilder).once();   
    } 
} 

我很高興能有測試現在建立,因爲它應該,但感覺很髒。我一直認爲[Test]塊在[Before]塊結束之前不會運行,但在這種測試條件下似乎不是這種情況。我認爲從我這裏得到的一個重要信息是,我的模擬服務的準備方式是否是這種測試的風格不佳,以及爲避免增加「睡眠」測試只是爲了購買時間,更好的方法是什麼? (可憐的風格本身恕我直言)

感謝您的提前輸入。

回答

1

我遇到類似的問題與Mockolate,我似乎記得閱讀由德魯提到他知道他們存在的答案。

我發現規則對於異步測試是可靠的,並且使用它們使得代碼更具可讀性。只需將MockolateRule和所需的模擬對象聲明爲成員變量(必須公開元數據才能正確拾取,並確保實例化規則!),然後使用mock(),否則就如nice()一樣使用。

[Rule] 
public var myRule:MockolateRule = new MockolateRule(); 

[Mock] 
public var myService:MyService; 

[Before] 
public function setUp():void { 
    myService = mock(MyService); 
} 

[Test] 
public function test():void { 
    assertNotNull(myService); 
} 
+0

我在想,重寫測試和放棄異步行爲可能是「正確」的方式。我不認爲我們的組織擁有最新的Mockolate和MockolateRule ......但是我確信也有舊版本的解決方案。謝謝,將返回我的調查結果。 – rwheadon

+0

如果有一種方法可以在不丟失準確性的情況下移除異步行爲,那麼我總是試着去做 - 測試越簡單,速度越快,可讀性越高。 MockolateRule已經存在了相當長的一段時間 - 如果你仍然使用一個真正的舊版本,那麼值得更新Mockolate ... – weltraumpirat

+0

我們有一個龐大的代碼庫,並且在更新Mockolate之後,新版本無法使用。我基本上不得不使用延遲添加的原始解決方案來運行。我確實嘗試使用另一個解決方案,使用mock()從網站,但結束了更多的錯誤。我確實接受這篇文章/答案是*正確*,儘管這不是我能夠運行的。非常感謝你。 – rwheadon