Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning out/ref parameters in Moq

Is it possible to assign an out/ref parameter using Moq (3.0+)?

I've looked at using Callback(), but Action<> does not support ref parameters because it's based on generics. I'd also preferably like to put a constraint (It.Is) on the input of the ref parameter, though I can do that in the callback.

I know that Rhino Mocks supports this functionality, but the project I'm working on is already using Moq.

like image 484
Richard Szalay Avatar asked Jul 01 '09 09:07

Richard Szalay


People also ask

How do you use out parameters?

For using out keyword as a parameter both the method definition and calling method must use the out keyword explicitly. The out parameters are not allowed to use in asynchronous methods. The out parameters are not allowed to use in iterator methods. There can be more than one out parameter in a method.

What is callback in MOQ?

Callbacks. A powerful capability of Moq is to attach custom code to configured methods and properties' getters and setters. This capability is often referred to as Callbacks.

What is verifiable in MOQ?

Verifiable is to enlist a Setup into a set of "deferred Verify(...) calls" which can then be triggered via mock. Verify() .


2 Answers

For 'out', the following seems to work for me.

public interface IService {     void DoSomething(out string a); }  [TestMethod] public void Test() {     var service = new Mock<IService>();     var expectedValue = "value";     service.Setup(s => s.DoSomething(out expectedValue));      string actualValue;     service.Object.DoSomething(out actualValue);     Assert.AreEqual(expectedValue, actualValue); } 

I'm guessing that Moq looks at the value of 'expectedValue' when you call Setup and remembers it.

For ref, I'm looking for an answer also.

I found the following QuickStart guide useful: https://github.com/Moq/moq4/wiki/Quickstart

like image 148
Craig Celeste Avatar answered Oct 10 '22 10:10

Craig Celeste


Moq version 4.8 (or later) has much improved support for by-ref parameters:

public interface IGobbler {     bool Gobble(ref int amount); }  delegate void GobbleCallback(ref int amount);     // needed for Callback delegate bool GobbleReturns(ref int amount);      // needed for Returns  var mock = new Mock<IGobbler>(); mock.Setup(m => m.Gobble(ref It.Ref<int>.IsAny))  // match any value passed by-ref     .Callback(new GobbleCallback((ref int amount) =>      {          if (amount > 0)          {              Console.WriteLine("Gobbling...");              amount -= 1;          }      }))     .Returns(new GobbleReturns((ref int amount) => amount > 0));  int a = 5; bool gobbleSomeMore = true; while (gobbleSomeMore) {     gobbleSomeMore = mock.Object.Gobble(ref a); } 

The same pattern works for out parameters.

It.Ref<T>.IsAny also works for C# 7 in parameters (since they are also by-ref).

like image 24
stakx - no longer contributing Avatar answered Oct 10 '22 10:10

stakx - no longer contributing