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()); }
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)); }
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)); }
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()); }
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)); }
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)); }
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); }
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()); }
private static string GetParametersRepresentation(MockDbCommand mockDbCommand) { var parameters = mockDbCommand.Parameters.Cast <DbParameter>(); return(string.Join(", ", parameters.Select(p => $"{p.ParameterName} = {p.Value}"))); }
public object ExecuteScalar(MockDbCommand command) { throw new NotImplementedException("When does Dapper ever use this?"); }