views:

679

answers:

4

I have an Enumerable array

int meas[] = new double[] {3, 6, 9, 12, 15, 18};

On each successive call to the mock's method that I'm testing I want to return a value from that array.

using(_mocks.Record()) {
  Expect.Call(mocked_class.GetValue()).Return(meas); 
}
using(_mocks.Playback()) {
  foreach(var i in meas)
    Assert.AreEqual(i, mocked_class.GetValue();    
}

Does anyone have an idea how I can do this?

A: 

IMHO, yield will handle this. http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx

Something like:

get_next() { foreach( float x in meas ) { yield x; } }

Vardhan Varma
How exactly would that work? I don't understand, Return does not accept a delegate type.
George Mauer
A: 

Any reason why you must have a mock here...
If not, I would go for a fake class.. Much Simpler and I know how to get it to do this :) I don't know if mock frameworks provide this kind of custom behavior.

Gishu
Mostly because a mock is less work and because I want to assert the method was called a minimum amount of time. Oh well, I might have to do that.
George Mauer
:) In this case, unless someone else posts a shorter rhino-mock version I'd go for a fake class and readability FTW.
Gishu
+1  A: 

If the functionality is the GetValue() returns each array element in succession then you should be able to set up multiple expectations eg

using(_mocks.Record()) {
  Expect.Call(mocked_class.GetValue()).Return(3); 
  Expect.Call(mocked_class.GetValue()).Return(6); 
  Expect.Call(mocked_class.GetValue()).Return(9); 
  Expect.Call(mocked_class.GetValue()).Return(12); 
  Expect.Call(mocked_class.GetValue()).Return(15); 
  Expect.Call(mocked_class.GetValue()).Return(18); 
}
using(_mocks.Playback()) {
  foreach(var i in meas)
    Assert.AreEqual(i, mocked_class.GetValue();    
}

The mock repository will apply the expectations in order.

Darren
+3  A: 

There is alway static fake object, but this question is about rhino-mocks, so I present you with the way I'll do it. The trick is that you create a local variable as the counter, and use it in your anonymous delegate/lambda to keep track of where you are on the array. Notice that I didn't handle the case that GetValue() is called more than 6 times.

var meas = new int[] { 3, 6, 9, 12, 15, 18 };
using (mocks.Record())
{
    int forMockMethod = 0;
    SetupResult.For(mocked_class.GetValue()).Do(
     new Func<int>(() => meas[forMockMethod++])
     );
}

using(mocks.Playback())
{
    foreach (var i in meas)
     Assert.AreEqual(i, mocked_class.GetValue());
}
bahadorn