Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSubstitute - Check arguments passed to method

We are currently in the process of moving from RhinoMocks to NSubstitute.

I have a method that takes an object of type DatabaseParams. This class has the following structure (simplified):

public class DatabaseParams
  {
    public string StoredProcName { get; private set; }
    public SqlParameter[] Parameters { get; private set; }

    public DatabaseParams(string storeProcName, SqlParameter[] spParams)
    {
      StoredProcName = storeProcName;
      Parameters = spParams;
    }
  }

I have the following method I want to check the arguments being passed to it are correct:

public interface IHelper
{
Task<object> ExecuteScalarProcedureAsync(DatabaseParams data);
}

How do I test that an instance of DatabaseParams was passed into that method with the correct values?

I could do this in RhinoMocks with something like this:

helperMock.Expect(m => m.ExecuteScalarProcedureAsync(Arg<DatabaseHelperParameters>.Matches(
        p =>   p.StoredProcName == "up_Do_Something"
            && p.Parameters[0].ParameterName == "Param1"
            && p.Parameters[0].Value.ToString() == "Param1Value"
            && p.Parameters[1].ParameterName == "Param2"
            && p.Parameters[1].Value.ToString() == "Param2Value"
        ))).Return(Task.FromResult<DataSet>(null));

The helperMock is mocking the interface IHelper that contains the ExecuteScalarProcedureAsync method.

like image 232
JBond Avatar asked Jul 09 '15 11:07

JBond


People also ask

How do you check if command execute (); has been received by a substitute?

In some cases (particularly for void methods) it is useful to check that a specific call has been received by a substitute. This can be checked using the Received() extension method, followed by the call being checked. In this case command did receive a call to Execute() , and so will complete successfully.

What is NSubstitute C#?

NSubstitute is a friendly substitute for . NET mocking libraries. It has a simple, succinct syntax to help developers write clearer tests. NSubstitute is designed for Arrange-Act-Assert (AAA) testing and with Test Driven Development (TDD) in mind. NSubstitute.Analyzers.CSharp.


2 Answers

I've figured out the answer myself.

NSubstitute just needs to use the .Received() call and then when you specify your argument to the method. You can specify the argument matching as a predicate.

For example:

  helperMock.Received().ExecuteScalarProcedureAsync(Arg.Is<DatabaseParams>(
   p =>   p.StoredProcName == "up_Do_Something"
        && p.Parameters[0].ParameterName == "Param1"
        && p.Parameters[0].Value.ToString() == "Param1Value"
        && p.Parameters[1].ParameterName == "Param2"
        && p.Parameters[1].Value.ToString() == "Param2Value"));
like image 140
JBond Avatar answered Oct 01 '22 18:10

JBond


An alternative is to use Do (see https://nsubstitute.github.io/help/actions-with-arguments/). I prefer this as it lets you call assertions against specific properties of the arguments, which gives you better feedback on which specific properties of the argument object are incorrect. For example:

StoredProc sp = null; // Guessing the type here

helperMock.Received().ExecuteScalarProcedureAsync(Arg.Do<DatabaseParams>(p => sp = p));

// NUnit assertions, but replace with whatever you want.
Assert.AreEqual("up_Do_Something", sp.StoredProcName);
Assert.AreEqual("Param1", p.Parameters[0].ParameterName);
Assert.AreEqual("Param1Value", p.Parameters[0].Value.ToString());
Assert.AreEqual("Param2", p.Parameters[1].ParameterName);
Assert.AreEqual("Param2Value", p.Parameters[1].Value.ToString());
like image 21
Castrohenge Avatar answered Oct 01 '22 16:10

Castrohenge