MachineSpecs Unit Testing Dapper

c# dapper

Question

So, because Dapper uses extension methods I wrapped up the functions I needed so I could stub it out:

public interface IDapperWrapper
{
    Task<IEnumerable<dynamic>> ExecuteQuery(string needArg, string sql, DynamicParameters parameterDictionary, CommandType commandType);
}

I passed in the DynamicParameters so this means my code creates these then passes to the DapperWrapper :)

So my Specs file looks something like:

public class MyUnitTest : WithSubject<ClassCallingDapperWrapper>
{
    protected static DynamicParameters DynamicParameters;

    private Establish context = () =>
    {
      The<IDapperWrapper>()
        .WhenToldTo(
            x =>
            x.ExecuteQuery(
                Param.IsAny<string>(),
                Param.IsAny<string>(),
                Param.IsAny<DynamicParameters>(),
                Param.IsAny<CommandType>()))
        .Return(
            (string org, string sql, DynamicParameters dynParm, CommandType cmdType) =>
            {
                DynamicParameters = dynParm;

                return Task.FromResult(response);
            });
    }

    private It should_call_dapper_with_correct_params = () =>
    {
      DynamicParameters dynParams = new DynamicParameters();
      dynParams.Add("@param1", "123");

      The<IDapperWrapper>().WasToldTo(x => x.ExecuteQuery(
              NeededArg,
              sql,
              Params.Any<DynamicParameters>(),
              CommandType.StoredProcedure));
    };

    // Here I want to check that the DynamicParameters static field has the same parameters as the one I passed through.
}

So how do I accomplish that last line. I've tried dynParams.Get<string>("param1"), but then read another post that says you need to read first.

I have accomplished this by encapsulating the DynamicParamters in the DapperWrapper class and passing through a Dictionary<string, object>, but not only does this increase code. It also increases the amount of un-testable code in the DapperWrapper which isn't ideal.

Ignore the fact that this spec won't run - it has been purposefully shrunk

Popular Answer

I hear you. I am running into the same issues and I either have to abandon using DynamicParameters (use IEnumerable>), or do what you did. Even then in unit testing with mocks I have to do some sort of callback to capture the argument. I submitted a request to the Dapper team to allow access to the parameters private dictionary object, or provide additional method to allow us to view input parameter names and values.




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why