public IDataReader ExecuteReader(MockDbCommand command)
        {
            var setup = FindSetup(command, nameof(Query), nameof(QuerySingle));

            var methodCall       = (MethodCallExpression)setup?.Body;
            var method           = methodCall?.Method ?? queryObjectMethod;
            var parametersLookup = command.GetParameterLookup();
            var parametersArray  = (from param in method.GetParameters()
                                    let commandValue = parametersLookup.ContainsKey(param.Name)
                                    ? parametersLookup[param.Name]
                                    : param.DefaultValue
                                                       select commandValue).ToArray();

            var result = method.Invoke(this, parametersArray);
            var reader = result as IDataReader;

            if (result == null)
            {
                if (method.Name == nameof(QuerySingle))
                {
                    return(GetQuerySingleDataReader(command, method.GetGenericArguments()[0]));
                }

                return(GetEmptyDataReader(command));
            }

            return(reader ?? result.GetDataReader());
        }
Exemple #2
0
        private static InvalidOperationException GetIdentityNotFoundException(MockDbCommand mockDbCommand)
        {
            return(new InvalidOperationException(
                       $@"Unable to detect the identity for the command, it could have been one of {QueryCache.Keys.Count} possible options.

command: '{mockDbCommand.CommandText}'
Parameters: `{GetParametersRepresentation(mockDbCommand)}`
CommandType: {mockDbCommand.CommandType}

To be able to Verify the Dapper call accurately the Command and Parameters (and return type) must be unique for every invocation of a Dapper method."));
        }
        public int ExecuteNonQuery(MockDbCommand command)
        {
            var parametersLookup = command.GetParameterLookup();
            var parametersArray  = (from param in executeMethod.GetParameters()
                                    let commandValue = parametersLookup.ContainsKey(param.Name)
                                     ? parametersLookup[param.Name]
                                     : param.DefaultValue
                                                       select commandValue).ToArray();

            return((int)executeMethod.Invoke(this, parametersArray));
        }
Exemple #4
0
        internal object ExecuteScalar(MockDbCommand command, bool isAsync, CancellationToken cancellationToken, MethodBase dapperMethod)
        {
            var method           = _methodFinder.FindUserMethodFromMethodInCallStack(dapperMethod, new Type[0]);
            var parametersLookup = command.GetParameterLookup(isAsync, cancellationToken);
            var parametersArray  = method.GetValues(parametersLookup);

            var value = new ScalarValue(isAsync, method, parametersArray, this);

            return(method.IsGenericMethod
                ? value
                : value.ToType(typeof(object), null));
        }
Exemple #5
0
        private static Dapper.SqlMapper.Identity SingleIdentityIfTextMatches(MockDbCommand mockDbCommand, IIdentityComparer identityComparer)
        {
            if (QueryCache.Keys.Count != 1)
            {
                return(null);
            }

            return(QueryCache.Keys
                   .Cast <Dapper.SqlMapper.Identity>()
                   .Where(id => identityComparer.TextMatches(mockDbCommand, id))
                   .SingleOrDefault());
        }
Exemple #6
0
        internal int ExecuteNonQuery(MockDbCommand command, bool isAsync, CancellationToken cancellationToken, MethodBase dapperMethod, Type dataType)
        {
            var genericArguments = dataType == null
                ? new Type[0]
                : new[] { dataType };
            var method           = _methodFinder.FindUserMethodFromMethodInCallStack(dapperMethod, genericArguments);
            var parametersLookup = command.GetParameterLookup(isAsync, cancellationToken);
            var parametersArray  = method.GetValues(parametersLookup);

            return(isAsync
                ? (int)TaskHelper.GetResultOfTask(method.Invoke(this, parametersArray))
                : (int)method.Invoke(this, parametersArray));
        }
Exemple #7
0
        private static InvalidOperationException GetIdentityAmbiguousException(MockDbCommand mockDbCommand, IReadOnlyCollection <string> ambiguous)
        {
            var commandType = mockDbCommand.CommandType == 0
                ? CommandType.Text
                : mockDbCommand.CommandType;

            return(new InvalidOperationException(
                       $@"Unable to detect the required response type for the command, it could be one of {ambiguous.Count} possible options.

Command: '{mockDbCommand.CommandText}'
Parameters: `{GetParametersRepresentation(mockDbCommand)}`
CommandType: {commandType}

To be able to Verify the Dapper call accurately the Command and Parameters (and return type) must be unique for every invocation of a Dapper method.

Possible options: {string.Join(", ", ambiguous)}

If this issue cannot be resolved, consider setting `Dapper.MoqTests.Settings.ResetDapperCachePerCommand` to `true`, note this is not a thread-safe approach"));
        }
        private LambdaExpression FindSetup(MockDbCommand command, params string[] dapperExtensionMethodNames)
        {
            var comparer   = new DapperSetupComparer(dapperExtensionMethodNames);
            var expression = this.setups.SingleOrDefault(comparer.Matches) as LambdaExpression;

            if (expression == null)
            {
                return(null);
            }

            var methodCallComparer = DapperMethodCallComparer.GetComparerForExpression(expression);

            if (methodCallComparer.CommandMatchesExpression(command))
            {
                return(expression);
            }

            return(null);
        }
        public bool CommandMatchesExpression(MockDbCommand command)
        {
            var visitor           = new MatchAnonymousObjectExpressionVisitor();
            var comparisonVisitor = (MethodCallExpression)visitor.Visit(methodCallExpression);

            var call = comparisonVisitor.Method.GetParameters()
                       .Zip(comparisonVisitor.Arguments, (methodArg, callArg) => new { methodArg, callArg })
                       .ToDictionary(a => a.methodArg, a => a.callArg);

            var expectedParameters = command.GetParameterLookup();
            var parameterValues    = from arg in call
                                     let match = ResolveToMatch(arg.Value as MethodCallExpression)
                                                 let paramValue = expectedParameters.ContainsKey(arg.Key.Name)
                    ? expectedParameters[arg.Key.Name]
                    : null
                                                                  select new { arg, matches = match.Matches(paramValue) };

            return(parameterValues.All(a => a.matches));
        }
Exemple #10
0
        internal static Dapper.SqlMapper.Identity GetIdentity(MockDbCommand mockDbCommand, IIdentityComparer identityComparer)
        {
            var identities = QueryCache.Keys
                             .Cast <Dapper.SqlMapper.Identity>()
                             .Where(id => identityComparer.Matches(mockDbCommand, id))
                             .ToArray();

            if (identities.Length <= 1)
            {
                return(identities.SingleOrDefault()
                       ?? SingleIdentityIfTextMatches(mockDbCommand, identityComparer)
                       ?? throw GetIdentityNotFoundException(mockDbCommand));
            }

            var ambiguous = identities.Select(id => $"`{id.type?.FullName ?? "<untyped>"}`")
                            .OrderBy(id => id)
                            .ToArray();

            throw GetIdentityAmbiguousException(mockDbCommand, ambiguous);
        }
Exemple #11
0
        internal IDataReader ExecuteReader(MockDbCommand command, bool isAsync, CancellationToken cancellationToken, MethodBase dapperMethod, params Type[] dataTypes)
        {
            var method           = _methodFinder.FindUserMethodFromMethodInCallStack(dapperMethod, dataTypes);
            var parametersLookup = command.GetParameterLookup(isAsync, cancellationToken);
            var parametersArray  = method.GetValues(parametersLookup);

            var result = method.Invoke(this, parametersArray);
            var reader = result as IDataReader;

            if (result == null)
            {
                if (IsSingleResultMethod(method))
                {
                    return(GetQuerySingleDataReader(method.GetGenericArguments()[0]));
                }

                return(GetEmptyDataReader(command));
            }

            return(reader ?? result.GetDataReader());
        }
Exemple #12
0
        private static string GetParametersRepresentation(MockDbCommand mockDbCommand)
        {
            var parameters = mockDbCommand.Parameters.Cast <DbParameter>();

            return(string.Join(", ", parameters.Select(p => $"{p.ParameterName} = {p.Value}")));
        }
Exemple #13
0
 public object ExecuteScalar(MockDbCommand command)
 {
     throw new NotImplementedException("When does Dapper ever use this?");
 }