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

in string parameter verifying doesn't work in some cases #808

Closed
wholegroup opened this issue Apr 15, 2019 · 5 comments
Closed

in string parameter verifying doesn't work in some cases #808

wholegroup opened this issue Apr 15, 2019 · 5 comments

Comments

@wholegroup
Copy link

moq 4.10.1

        public interface ISome
        {
            string bad(in string text);
        }

        [Test]
        public void testMoq()
        {
            var m = new Mock<ISome>();
            m.Setup(foo => foo.bad("test")).Verifiable();
            m.Object.bad("test.".TrimEnd('.')); // it doesn't work
//            m.Object.bad("test"); // it works well
            m.Verify();
        }
@stakx
Copy link
Contributor

stakx commented Apr 15, 2019

Why are you passing string using in? System.String is already a reference type, and as such will be passed by-reference anyway.

@wholegroup
Copy link
Author

@stakx
I use in modifier to mark variables as immutable. It's kind of final in Java. Microsoft calls this 'readonly references'.

@stakx
Copy link
Contributor

stakx commented Apr 15, 2019

in was introduced to be used mostly in conjunction with value types.
Of course it's your decision to use it however you want. Just be aware that Moq has certain rules when it comes to matching by-ref arguments (which align more with how by-ref parameters are typically employed), which you'll need to follow if you want to continue using in your way.

P.S.: The reason one of your invocations is matched while the other isn't most likely has to do with string interning.

m.Object.bad("test.".TrimEnd('.')); // it doesn't work
// m.Object.bad("test"); // it works well

When using the string constant "test", both the setup and the invocation refer to the exact same string instance in both cases due to interning. When you use a string expression "test.".TrimEnd('.'), a new, distinct string object will get computed that does not reference-equal the "test" string instance. To test that theory, try calling your method with an argument string.Intern("test.".Trim('.')) and see what happens.

@stakx stakx closed this as completed Apr 15, 2019
@wholegroup
Copy link
Author

@stakx

Thank you for your help and fast response! I definitely used in in the wrong way.

When using the string constant "test", both the setup and the invocation refer to the exact same string instance in both cases due to interning. When you use a string expression "test.".TrimEnd('.'), a new, distinct string object will get computed that does not reference-equal the "test" string instance. To test that theory, try calling your method with an argument string.Intern("test.".Trim('.')) and see what happens.

@stakx
Copy link
Contributor

stakx commented Apr 16, 2019

Glad I could help. 😃

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