Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Comercial
    • Calculadora

0

65
Vistas
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.

9 months ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

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"));
9 months ago · Santiago Trujillo Denunciar

0

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());
9 months ago · Santiago Trujillo Denunciar

0

A bit late for the party, but ran into the same need. I am working with mockito in java, and they have an Argument capture helper that I like. It is basically the same as @Castrohenge answer

So here is my NSubstitute implementation.

public interface IFoo
{
    void DoSomthing(string stringArg);
}

Argument capture class

public class ArgCapture<T>
{
    private List<T> m_arguments = new List<T>();

    public T capture()
    {
        T res = Arg.Is<T>(obj => add(obj)); // or use Arg.Compat.Is<T>(obj => add(obj)); for C#6 and lower
        return res;
    }

    public int Count
    {
        get { return m_arguments.Count; }
    }

    public T this[int index]
    {
        get { return m_arguments[index]; }
    }

    public List<T> Values {
        get { return new List<T>(m_arguments);}
    }

    private bool add(T obj)
    {
        m_arguments.Add(obj);
        return true;
    }
}

And the usage test case

    [Test]
    public void ArgCaptureTest()
    {
        IFoo foo1 = Substitute.For<IFoo>();
        ArgCapture<string> stringArgCapture = new ArgCapture<string>();
        foo1.DoSomthing("firstCall");
        foo1.DoSomthing("secondCall");
        foo1.Received(2).DoSomthing(stringArgCapture.capture());
        Assert.AreEqual(2,stringArgCapture.Count);
        Assert.AreEqual("firstCall",stringArgCapture[0]);
        Assert.AreEqual("secondCall", stringArgCapture[1]);
    }
9 months ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos