Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking a method that takes a delegate in RhinoMocks

I have the following classes:

public class HelperClass  
{  
    HandleFunction<T>(Func<T> func)
    {
         // Custom logic here

         func.Invoke();

         // Custom logic here  
}

// The class i want to test  
public class MainClass
{
    public readonly HelperClass _helper;

    // Ctor
    MainClass(HelperClass helper)
    {
          _helper = helper;
    }

    public void Foo()
    {
         // Use the handle method
         _helper.HandleFunction(() =>
        {
             // Foo logic here:
             Action1();
             Action2(); //etc..
        }
    }
}

I want to test MainClass only. I a using RhinoMocks to mock HelperClass in my tests.
The problem is, while I am not interested in testing the HandleFunction() method I am interested in checking Action1, Action2 and other actions that were sent to HandleFunction() when called..
How can I mock the HandleFunction() method and while avoiding it's inner logic, invoke the code that was sent to it as a parameter?

like image 364
Pavel Tarno Avatar asked Jan 28 '13 10:01

Pavel Tarno


2 Answers

Because your unit under test most probably requires the delegate to be called before proceeding, you need to call it from the mock. There is still a difference between calling the real implementation of the helper class and the mock implementation. The mock does not include this "custom logic". (If you need that, don't mock it!)

IHelperClass helperMock = MockRepository.GenerateMock<IHelperClass>();
helperMock
  .Stub(x => x.HandleFunction<int>())
  .WhenCalled(call => 
  { 
    var handler = (Func<int>)call.Argument[0];
    handler.Invoke();
  });

// create unit under test, inject mock

unitUnderTest.Foo();
like image 88
Stefan Steinegger Avatar answered Nov 19 '22 11:11

Stefan Steinegger


In addition to Stefan's answer I'd like to show quite another way to define stub which invokes passed argument:

handler
    .Stub(h => h.HandleFunction(Arg<Func<int>>.Is.Anything))
    .Do((Action<Func<int>>)(func => func()));

Please read more about Do() handler here and here.

like image 23
Alexander Stepaniuk Avatar answered Nov 19 '22 09:11

Alexander Stepaniuk