ayende/rhino-mocks

Can't mock methods with parameters decorated with OutAttribute that are not byref.

Opened this issue · 0 comments

(Sorry for the duplicate, I closed the previous one by mistake and there doesn't seem to be a way to reopen it. )

This fails:


    public class OutAttributeIssues
    {
        [Fact]
        public void When_argument_includes_outattribute_but_is_not_a_byref_type_it_shouldnt_require_that_it_be_specified_using_ArgTOut()
        {
            MockRepository mocks = new MockRepository();
            
            var theMock = mocks.StrictMock();
            
            int expected = 30;
            
            theMock.Expect(m => m.SomeMethod(Arg.Is.Anything)).Return(expected);
            theMock.Replay();
            
            var result = theMock.SomeMethod("test");
            Assert.Equal(expected, result);
        }
    }
    
    public interface IHaveAnOutAttribute
    {
        int SomeMethod([System.Runtime.InteropServices.OutAttribute] string someValue);
    }

Removing the OutAttribute fixes the test.

The OutAttribute only sets the Out flag for the parameter, but doesn't change anything from the caller's point of view. It is only when the parameter type is a ByRef type that the signature of the method actually changes (say from string to string&).

This change fixes my test above and it doesn't break any of the others, but I can't say I know exactly what I'm doing with it, nor I have any clue how it affects the marshalling scenarios the OutAttribute is supposed to be used for:

I ran into this issue trying to create a Stream mock. The Read method's buffer attribute is marked wtih the OutAttribute.

--- a/Rhino.Mocks/ArgManager.cs
+++ b/Rhino.Mocks/ArgManager.cs
@@ -139,7 +139,7 @@ namespace Rhino.Mocks
 
            for (int i = 0; i < parameters.Length; i++)
            {
-               if (parameters[i].IsOut)
+               if (parameters[i].IsOut && parameters[i].ParameterType.IsByRef)
                {
                    if (args[i].InOutRef != InOutRefArgument.OutArg)
                    {