Verify value of reference parameter with Moq

前端 未结 4 1404
南方客
南方客 2021-01-03 23:30

I just switched to Moq and have run into a problem. I\'m testing a method that creates a new instance of a business object, sets the properties of the object from user inpu

相关标签:
4条回答
  • 2021-01-03 23:48

    I have encountered similar issue. Bit I got the solution by using the latest Moq and passing the value like

    var instance = new Bar(); Mock.Setup(foo => foo.Submit(ref instance)).Returns(true);

    Earlier as well, I was using the same method, but i was not getting return as true.

    Inside the actual function instance was getting created and overwriting the instance passed from the unit test class was causing the issue. I removed instance creation inside the actual class and then it worked.

    Hope it will help you.

    thanks

    0 讨论(0)
  • 2021-01-03 23:49

    Unfortunately, I am not sure that this is possible without direct support from Moq. The problem is that Lambda expressions do not support ref or out.

    "A lambda expression cannot directly capture a ref or out parameter from an enclosing method. "

    http://msdn.microsoft.com/en-us/library/bb397687.aspx

    I can't even get an example like yours to work. Adding ref to the setup fails to compile.

    You might want to check out the Moq discussions for more http://groups.google.com/group/moqdisc

    Good luck.

    0 讨论(0)
  • 2021-01-03 23:58

    I can't offer you an exact solution, but an alternative would be to hide the pass-by-ref semantics behind an adapter, which takes the parameter by value and forwards it to the RemotingHandler. This would be easier to mock, and would remove the "ref" wart from the interface (I am always suspicious of ref parameters :-) )

    EDIT:

    Or you could use a stub instead of a mock, for example:

    public class StubRemotingHandler : IRemotingHandler
    {
        public CustomerContact savedContact;
    
        public void SaveCustomerContact(ref CustomerContact contact)
        {
            savedContact = contact;
        }
    }
    

    You can now examine the saved object in your test:

    IRemotingHandler remote = new StubRemotingHandler();
    ...
    //pass the stub to your object-under-test
    ...
    target.AddContact();
    Assert.AreEqual(expected, remote.savedContact);
    

    You also say in your comment:

    I'd hate to start a precedent of wrapping random bits of the backend so I can write tests more easily

    I think that's exactly the precedent you need to set! If your code isn't testable, you're going to keep struggling to test it. Make it easier to test, and increase your coverage.

    0 讨论(0)
  • 2021-01-04 00:05

    The latest version of Moq supports this scenario.

    Taken from the quickstart at http://code.google.com/p/moq/wiki/QuickStart:

    // ref arguments
    var instance = new Bar();
    // Only matches if the ref argument to the invocation is the same instance
    mock.Setup(foo => foo.Submit(ref instance)).Returns(true);
    
    0 讨论(0)
提交回复
热议问题