ayende/rhino-mocks

Expect throws InvalidCastException with delegates

Opened this issue · 2 comments

Hi*
I have the following issue when mocking interface that has a method that returns Func delegate.
Please see the following code:

Dummy class model just to show the issue

public interface ITest<T>
{  
     Func<T> Get(string text);
}

public interface IParam
{
    string Text { get; }
}

public class Param : IParam
{
    public string Text { get; set; }
}

Mocking code looks like this

  var mock = MockRepository.GenerateMock<ITest<IParam>>();
  mock.Expect(m => m.Get("Test1")).Return( () => new Param { Text = "ParamWithText1" }); //OK
  mock.Expect(m => m.Get("Test2")).Return( () => new Param { Text = "ParamWithText2" }); //Exception

The issue is that the fist expect runs without any problems (suppose that I commented second one) but with the second it throws InvalidCastException exception.

Message

 Unable to cast object of type
'Castle.Proxies.ProxyDelegate_Func`1_1Proxye77fc793043240708536f884e313f671' to type 'System.Func`1[IParam]'.

I tried different combination and I suspect that there are some issue with delegate but strange thing is that the first time is passes.

I would be grateful for any ideas if I'm missing something or how to solve it.

Thanks,
Norbert Raus

Hello,
I couldn't wait so long for response so I analized why rhino was confused with second expectation. It turned out that in RecordMockState class there is a method called TryCreateReturnValue which evaluates return object from a expectation. There is a foreach statement with iterates through DependedMocks where after first expectation first mock is added. Then it tries to use already created results that was alread created if the following condition is met:
type == expectation.Method.ReturnType
where type is item from dependentMock.ImplementedTypes.

I have checked my situation it passes this condition but later on there is this code.
returnValue = dependentMock.MockedObjectInstance;
For my situation the above condition is not enough after adding:
expectation.Method.ReturnType.IsAssignableFrom(dependentMock.MockedObjectInstance.GetType())

started working.... I run all rhino unit tests to see if this breaks and one test if failing :
FieldProblem_LAFAY.

Can someone verify if this is bug or I'm missing something. For now is seems that it works for me (I'm not using marshaled objects -> failing test).

Thanks,
Norbert Raus

This test seems to run without problems with alaendle@8be5a7a (https://github.com/downloads/alaendle/rhino-mocks/Rhino.Mocks-3.6-Build-025dc58.zip).

[Fact]
public void Test()
{
  var mock = MockRepository.GenerateMock<ITest<IParam>>();
  mock.Expect(m => m.Get("Test1")).Return(() => new Param { Text = "ParamWithText1" }); // OK
  mock.Expect(m => m.Get("Test2")).Return(() => new Param { Text = "ParamWithText2" }); // Exception

  Assert.Equal("ParamWithText1", mock.Get("Test1")().Text);
  Assert.Equal("ParamWithText2", mock.Get("Test2")().Text);

  mock.VerifyAllExpectations();
}

Nevertheless I've added this test to the code base (alaendle@1300043).

Br,
Andreas