簡體   English   中英

Rhino Mocks 使用存根函數的輸入參數來創建返回值

[英]Rhino Mocks use input parameters of stubbed function to create return value

我有兩個接口:

interface ITimeframe
{
    DateTime beginTime {get;}
    DateTime endTime {get;}
}

interface ITimeframeFactory
{
     ITimeframe Create(Datetime beginTime, DateTime endTime);
}

我的測試對象使用 ITimeframeFactory 來創建多個 ITimeframes。 為了測試我的 TestObject,我給它一個模擬的 TimeframeFactory。 因為我的測試對象處理創建的時間范圍,模擬的 TimeframeFactory 需要創建返回正確值的模擬時間范圍。

StackOverflow: How to stub a function似乎暗示了這個方向:use WhenCalled:

var mockRepository = new MockRepository();
ITimeframeFactory mockedTimeframeFactory = mockRepository.Stub<ITimeFrameFactory>();

// when the mocked TimeframeFactory is asked to Create a timeframe,
// let it return a new mockedTimeFrame that returns the proper values for BeginTime and EndTime
using (mockRepository.Record())
{
    mockedTimeframeFactory.Stub( (factory) => factory.Create(
        Arg<DateTime>.Is.Anything,
        Arg<DateTime.Is.Anything))
        .WhenCalled( (call) =>
        {
            DateTime beginTime = (DateTime)call.Arguments[0];
            DateTime endTime = (DateTime)call.Arguments[1];

            // mock a new ITimeframe;
            // this ITimeframe should return beginTime and endtime:
            ITimeframe createdTimeframe = mockRepository.Stub<ITimeframe>();
            createdTimeframe.Stub((timeframe) => timeframe.BeginTime).Return(beginTime);
            createdTimeframe.Stub((timeframe) => timeframe.EndTime).Return(endTime);
            call.ReturnValue = createdTimeframe;
        });
}

用法:

using (mockRepository.Playback())
{
    DateTime beginTime = new DateTime(2020, 1, 1);
    DateTime endTime = new DateTime(2019, 2, 2);

    ITimeframe createdTimeframe = mockedFactory.Create(beginTime, endTime);
    Assert.IsNotNull(createdTimeframe);

    DateTime mockedBeginTime = createdTimeframe.BeginTime;
    DateTime mockedEndTime = createdTimeframe.EndTime;

    Assert.AreEqual(beginTime, mockedBeginTime);
    Assert.AreEqual(endTime, mockedEndTime);
}

在 mockedFactory.Create(...) 我看到WhenCalled被處理。 在 WhenCalled 期間,它具有正確的 beginTime 和 endTime。

call.ReturnValue也適用,因為畢竟在調用創建createdTimeframe不為空。

但是,當我想檢查 createdTimeframe 的屬性時,出現異常:

System.InvalidOperationException: '上一個方法'ITimeframe.get_BeginTime();' 需要返回值或拋出異常。

似乎 createdTimeframe.Stub 的存根無效?

如何解決這個問題?

解決方案比我想象的要容易:在回放期間,當創建模擬時間范圍時,這個模擬時間范圍仍處於記錄狀態。

我所要做的就是通過調用Replay()將其設置為重播狀態。

這樣我就可以創建幾個不同的時間幀,如下面的代碼所示。

using (this.mockRepository.Playback())
{
    List<ITimeframe> createdTimeframes = new List<ITimeframe>();
    DateTime beginTime = new DateTime(2020, 1, 1);
    DateTime endTime = new DateTime(2019, 2, 2);


    for (int i = 0; i < 10; ++i)
    {
        Timeframe createdTimeframe = this.mockedFactory.Create(beginTime, endTime);

        // This should be a new Timeframe, not returned before
        Assert.IsNotNull(createdTimeframe);
        Assert.IsFalse(createdTimeframes.Contains(createdTimeframe));
        createdTimeframes.Add(createdTimeframe);

        // before using the stubs of this timeframe set in in playback:
        createdTimeframe.Replay();
        DateTime mockedBeginTime = createdTimeframe.BeginTime;
        DateTime mockedEndTime = createdTimeframe.EndTime;
        Assert.AreEqual(beginTime, mockedBeginTime);
        Assert.AreEqual(endTime, mockedEndTime);

        // change beginTime and endTime to create a new timeframe
        beginTime = beginTime.AddMonths(i);
        endTime = endTime.AddMonths(-i);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM