1

I'm using the Moq framework. I'm trying to mock data from a function call, but the problem is, the function RETURNS a boolean, and the response data comes out of an OUT variable in the form of BsonArray. How can I mock this out variable?

database.runQuery(query, out BsonArray result, out err, out errorMessage);

How do we setup this function to be available for mocking? e.g. mock.Setup(x => x.runQuery(It.IsAnyblahblah)

I've tried before and failed. Help me

jamie
  • 176
  • 1
  • 12
  • `(out It.IsAny)`? –  Dec 23 '20 at 12:29
  • 2
    Does this answer your question? [Assigning out/ref parameters in Moq](https://stackoverflow.com/questions/1068095/assigning-out-ref-parameters-in-moq) –  Dec 23 '20 at 12:30
  • No as the answers referred to ref params, not out params – jamie Dec 24 '20 at 10:51

3 Answers3

1

Set up a delegate with the appropriate signature:

public delegate void OutAction<T1, T2, T3, T4>(T1 arg1, out T2 arg2, out T3 arg3, out T4 arg4);

Declare variables to accept your out values (where P1, P3 and P4 are the types for those variables):

var test_result = new BsonArray(); // I'm not familiar with this class, so this is just a guess
var test_err = new P3();
var test_errorMessage = new P4();

Then create your mock

mock
  .Setup(x => x.runQuery(It.IsAny<P1>(), out It.IsAny<BsonArray>(), out It.IsAny<P3>(), out It.IsAny<P4>()))
  .Callback(new OutAction<P1,BsonArray,P3,P4>((P1 var1, out BsonArray var2, out P3 var3, out P4 var4) => { _code_to_set_the_values_of_var2_var3_and_var4; }))
  .Returns _desired_return_value_for_runQuery;

You can find out more here or here

  • I do not yet have enough reputation to comment on jamie's answer below, so I will post my response here: Jamie: please note that your solution has what could be a severe limitation. It will only allow the out parameters to return the values that they have been assigned at the time that the mock.Setup() statement is called. In your case, that means that result will always return {..Whatever data you have}, err will always return default for State, and errorMessage will always return default for string. Depending on your test scenario, this may suffice and be acceptable. In other cases - no. – Clive Pottinger Dec 29 '20 at 22:11
1

here's how I Moq out params:

delegate void SubmitTest(out string  mystring );

string sentSql = string.Empty;
string  functionResult = string.Empty;;
Mock.setup(x=>x.runQuery(out It.ref<string>().IsAny))
.Callback( new SubmitTest( (out string  mystring) => 
{
   sentSql = mystring;  // see what was sent
   functionresult  = somefunctionCall(mySql) ; if  i was calling  function
}
.Returns( 
   // can use  "select * From customer";
   // or sentSql
);
wesreitz
  • 79
  • 6
1

I've found out my answer in a much nicer way than using callbacks/delegates.

bsonArray result = {..Whatever data you have};
State err = default;
string errorMessage = default;
mock.Setup(x => x.runQuery(It.IsAny<string>(), out result, out err, out errorMessage);
jamie
  • 176
  • 1
  • 12