2010-03-29 73 views
3

我對使用MSpec相對較新,而且隨着我編寫越來越多的測試,減少重複變得很明顯,您經常必須使用基類作爲您的設置我覺得使用AssertWasCalled方法來驗證我的期望很高興,但是你在哪裏設置了存根的返回值,我發現它有助於在基類中設置上下文,以注入我的依賴關係,但是(我認爲)意味着我需要將我的存根設置在因爲委託只是感覺錯誤。當使用模擬框架和MSPEC在哪裏設置存根

有沒有更好的方法我錯過了?

回答

7

存根的初始化/設置屬於排列階段。安排階段用於在運動之前使系統進入已知狀態。

在MSpec中,排列階段在Establish字段中執行。例如:

public class When_the_temperature_threshold_is_reached 
{ 
    static ITemperatureSensor Sensor; 
    static Threshold Threshold; 

    Establish context =() => 
     { 
      Sensor = MockRepository.GenerateStub<ITemperatureSensor>(); 
      Sensor 
       .Stub(x => x.GetTemperature()) 
       .Return(42); 

      Threshold = new Threshold(Sensor); 
     }; 

    Because of =() => Reached = Threshold.IsReached(40); 

    It should_report_that_the_threshold_was_reached = 
     () => Reached.ShouldBeTrue(); 
} 

當你寫使用那種ITemperatureSensor更多的測試,你應該從中提取基類,它複雜或重複設置。

public abstract class TemperatureSpecs 
{ 
    protected static ITemperatureSensor CreateSensorAlwaysReporting(int temperature) 
    { 
     var sensor = MockRepository.GenerateStub<ITemperatureSensor>(); 
     sensor 
      .Stub(x => x.GetTemperature()) 
      .Return(temperature); 

     return sensor; 
    } 
} 

public class When_the_temperature_threshold_is_reached : TemperatureSpecs 
{ 
    // Everything else cut for brevity. 
    Establish context =() => 
     { 
      Sensor = CreateSensorAlwaysReporting(42); 

      Threshold = new Threshold(Sensor); 
     }; 
} 

這給了你,你可以從上下文本身影響存根的返回值的優勢在於:通過保持儘可能多的信息儘可能本地的環境下,你這樣做,對於「設置」方法提供了一個好名字在基類中。

沒有必要指定或期待Because中的任何存根相關。當Because運行時,您的系統應該處於可以在沒有進一步準備的情況下運行的狀態。

+0

感謝亞歷山大,這是非常有道理的。我希望避免在每個派生類中設置上下文,但我認爲這是不可能的 – 2010-03-29 21:05:09

+1

'因爲'字段在建立類層次結構時按正確的順序執行。你可以完全做到這一點,但這不是一個好習慣。請記住,您希望儘可能多地保持與正在執行的上下文接近的信息。 – 2010-03-29 22:54:27