Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.13 callback with returns and out parameter ~ bug? #917

Closed
Rubenisme opened this issue Sep 2, 2019 · 5 comments
Closed

4.13 callback with returns and out parameter ~ bug? #917

Rubenisme opened this issue Sep 2, 2019 · 5 comments

Comments

@Rubenisme
Copy link

Rubenisme commented Sep 2, 2019

The following worked in 4.12:

using Moq;
using NUnit.Framework;

namespace Tests
{
    public interface ITest
    {
        int JustAMethod(string name, out string outParam);
    }

    public class Tests
    {
        private readonly Mock<ITest> _myMock = new Mock<ITest>();

        [Test]
        public void Test1()
        {
            string saveParamName;
            string outParam;
            _myMock.Setup(
                    tcm => tcm.JustAMethod(It.IsAny<string>(), out outParam))
                .Returns(30)
                .Callback((string name, string unused) => saveParamName = name);
        }
    }
}

But fails on 4.13 with this exception:

Test1 Failed: System.ArgumentException : Invalid callback. Setup on method with parameters (string, out string) cannot invoke callback with parameters (string, string).
System.ArgumentException : Invalid callback. Setup on method with parameters (string, out string) cannot invoke callback with parameters (string, string).
at Moq.MethodCall.SetCallbackResponse(Delegate callback)
at Moq.Language.Flow.SetupPhrase.Callback[T1,T2](Action`2 callback)
at Tests.Tests.Test1() in UnitTest1.cs:line 32

Looks like it has to do with this change.
Is this not a bug/breaking change?

Update: this also fails if you call 'Returns' first before 'Callback'.

@Rubenisme Rubenisme changed the title 4.13 callback after returns with out parameter bug? 4.13 callback with returns and out parameter ~ bug? Sep 2, 2019
@stakx
Copy link
Contributor

stakx commented Sep 2, 2019

Looks like it has to do with this change.

Correct. See this entry in the changelog:

Consistent Callback delegate validation regardless of whether or not Callback is preceded by a Returns: Validation for post-Returns callback delegates used to be very relaxed, but is now equally strict as in the pre-Returns case.) (@stakx, #876)

@stakx stakx closed this as completed Sep 2, 2019
@stakx
Copy link
Contributor

stakx commented Sep 2, 2019

Update: this also fails if you call 'Returns' first before 'Callback'.

Reopening. If that's correct, I'd like to take a closer look.

@stakx stakx reopened this Sep 2, 2019
@stakx
Copy link
Contributor

stakx commented Sep 2, 2019

The code posted above fails in Moq 4.12.0. It succeeds only when Callback is called after Returns.

The code posted above fails in Moq 4.13.0, regardless of whether Callback appears before or after Returns. So this is indeed what the changelog entry describes, i.e. this is not a bug, but an intended change.

@stakx stakx closed this as completed Sep 2, 2019
@Rubenisme
Copy link
Author

Thanks for the clarification and the prompt reply. Can you tell me how to save my variables now? I can't use the out keyword on the callback to have my callback's parameter types to match those on the method, can I?

@stakx
Copy link
Contributor

stakx commented Sep 3, 2019

delegate void JustAMethodCallback(string name, out string outParam);
...

_myMock.Setup(...).Callback(new JustAMethodCallback((string name, out string outParam) => ...);

The custom delegate type is necessary because Moq only provides overloads for Action and Func, all of which don't have any by-ref parameters. So you need to call the overload that accepts any Delegate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants