unosd / moq.dapper Goto Github PK
View Code? Open in Web Editor NEWMoq extensions for Dapper methods.
License: GNU General Public License v2.0
Moq extensions for Dapper methods.
License: GNU General Public License v2.0
Error message when trying to setup dapper for QueryFirstAsync or QueryFirstOrDefaultAsync.
Error Message:
System.NotSupportedException : Specified method is not supported.
Stack Trace:
at Moq.Dapper.DbConnectionInterfaceMockExtensions.SetupDapper[TResult](Mock1 mock, Expression
1 expression)
Either moq.dapper 1.0.4 should be retargeted to .Net Standard 2.0 (to maintain compatibility with projects consumer moq.dapper 1.0.3), or you should create a new major version (e.g. 2.0.0).
I am trying to simulate a query throwing an exception. So I can test how my code handles this.
I am doing a setup along the lines of
dbConnectionMock.SetupDapperAsync(mock =>
mock.QueryAsync<RowModel>(
It.IsAny<string>(),
It.IsAny<object>(),
null,
null,
null))
.ThrowsAsync(new Exception("error executing db query"));
The code errors whilst performing this setup and throws an exception with the following message:
One or more errors occurred. (error executing db query)
It appears almost as if my dummy exception is being thrown during the setup.
Am I doing something wrong?
Or is .ThrowsAsync not supported?
Thanks for making this library it is very useful
Tom
Thank you for publishing this project.
Does it support Dapper QueryMultipleAsync?
I am happy to help with this. I would really appreciate if you can point out some directions ๐.
Am trying to mock multimapping using this library and am not getting the support for the same.
Here is the multi mapping query.
`string sql = "SELECT * FROM Invoice AS A INNER JOIN InvoiceDetail AS B ON A.InvoiceID = B.InvoiceID;";
using (var connection = My.ConnectionFactory())
{
connection.Open();
var invoices = connection.Query<Invoice, InvoiceDetail, Invoice>(
sql,
(invoice, invoiceDetail) =>
{
invoice.InvoiceDetail = invoiceDetail;
return invoice;
},
splitOn: "InvoiceID")
.Distinct()
.ToList();
}`
Am trying to Mock this using the below code but am not able to achieve this? Can you resolve this as this methods everybody uses.
mockConnection.SetupDapper(c => c.Query<Invoice, InvoiceDetail, Invoice>(It.IsAny<string>(), null, null, null, true, "", null)) .Returns(fakeInvoice);
It seems that this library is published under GPL-2.0 license which forbids linking with proprietary (non-GPL compatible) code. Is this intentional?
I would like to use this library in my work, but I wouldn't want to get into any legal problems because of that.
When trying to moq with moq.dapper using an IDbTransaction, It seems to call but won't return the "returns".
Using the same call, I pass a null to the setup and the actual call, the returns works.
There are several Dapper functions exposed in Dapper.Contrib ...
T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();
Are you thinking about support these methods?
When will they be able to review the pullrequests and update the library? Or is it abandoned? If so, they could confirm us to create a fork and publish a corrected version in nuget. Currently I have problems with enumerators returning zero
After doing something like this:
connection.SetupDapper(c => c.Query<int>(It.IsAny<string>(), It.IsAny<InvoiceLine>(), null, true, null, null)).Returns(new List<int>());
Then trying to do:
connection.Verify(s => s.Query<int>(It.IsAny<string>(), It.IsAny<InvoiceLine>(), null, true, null, null), Times.Exactly(invoice.InvoiceLines.Count()));
The verify fails with a hard error...it's understandable, because the Query method doesn't really exist. Is there any way to make a verify work?
If I call a query with parameters is there currently anyway to access those values in the ReturnsAsync
method?
I need to access the data in my tests and store it for another query to use it.
Thanks
Hello, Is it posible to modify the license to MIT, BSD or Apache2?, Moq is under BSDv3 and it's posible to use it with commercial private software, but it's incompatible to use this library in this scenarios.
I am attempting to test a feature that relies on multiple QueryAsync; however, when apply the second setup, it overrides the first mock setup, even if T is different. I was hoping that it would work differently for different T's or by changing the SQL statement, but no luck. Code looks like this.
var mock = new Mock();
mock.SetupDapperAsync(c => c.QueryAsync(It.IsAny(), null, null, null, null)).ReturnsAsync(object1);
mock.SetupDapperAsync(c => c.QueryAsync(It.IsAny(), null, null, null, null)).ReturnsAsync(object2);
var expected = object1;
var actual = mock.Object.Query("", null, null, null, null).ToList(); // shows up as Object2.
I'll ask on SO to see if I'm missing something. Thanks for this great library.
There are a couple of queries in my repository that use Any() for dapper. While I was writing the unit test for it they all fail with the same error Value cannot be null.
Sample code
This is the method which I want to test
public IEnumerable<SiteRemotePrefixResponse> CheckIfPrefixExistsForSiteIds(string siteIds, DateTimeOffset startDateTime, DateTimeOffset endDateTime)
{
var query = string.Empty;
var responses = Enumerable.Empty<SiteRemotePrefixResponse>();
using (var dbConnection = Connection.CreateDbConnection())
{
dbConnection.Open();
query = $@"SELECT siteId,
CASE COUNT(prefix) WHEN 0 THEN 0 ELSE 1 END AS isAvailable
FROM ABC
WHERE site_id = ANY(@SiteId)
AND bucket_start BETWEEN '{startDateTime.DateTime:yyyy-MM-dd HH:mm:ss}' AND '{endDateTime.DateTime:yyyy-MM-dd HH:mm:ss}'
GROUP BY site_id
ORDER BY 2 DESC
";
var siteArray = siteIds.Split(',');
var parameters = new { SiteId = siteArray };
responses = dbConnection.Query<SiteRemotePrefixResponse>(query, parameters, commandTimeout: 600);
}
return responses;
}
Unit test for this method
[Fact]
public void CheckIfRemotePrefixExistsForSiteIds_OkResult()
{
//ARRANGE
var siteIds = "'SIT-1234','SIT-3456'";
var startDateTime = DateTime.Now.AddDays(-1);
var endDateTime = DateTime.Now;
var siteRemotePrefixResponses = MockedEntitiesRepository.mockedSiteRemotePrefixResponses;
var siteArray = siteIds.Split(',');
var parameters = new { SiteId = siteArray };
mockedDbConnection.SetupDapper(x => x.Query<SiteRemotePrefixResponse>(It.IsAny<string>(), parameters, null, true, 600, null)).Returns(siteRemotePrefixResponses);
//ACT
var result = repository.CheckIfRemotePrefixExistsForSiteIds(siteIds, startDateTime, endDateTime);
//ASSERT
Assert.Equal(JsonConvert.SerializeObject(siteRemotePrefixResponses), JsonConvert.SerializeObject(result));
}
This is the stacktrace
at System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator)
at System.Text.RegularExpressions.Regex.Replace(String input, String pattern, MatchEvaluator evaluator, RegexOptions options)
at Dapper.SqlMapper.PackListParameters(IDbCommand command, String namePrefix, Object value) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2086
at Dapper.CommandDefinition.SetupCommand(IDbConnection cnn, Action`2 paramReader) in C:\projects\dapper\Dapper\CommandDefinition.cs:line 129
at Dapper.SqlMapper.<QueryImpl>d__138`1.MoveNext() in C:\projects\dapper\Dapper\SqlMapper.cs:line 1078
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in C:\projects\dapper\Dapper\SqlMapper.cs:line 723
at XCASystemAPI.Core.Repository.CheckIfRemotePrefixExistsForSiteIds(String siteIds, DateTimeOffset startDateTime, DateTimeOffset endDateTime) in Repository.cs:line 366
at SystemAPI.Tests.API.RepositoryTest.CheckIfRemotePrefixExistsForSiteIds_OkResult() in RepositoryTest.cs:line 149
Kindly suggest what could be done to solve this error.
I get this error when I try to use Moq.Dapper with the latest version of Moq.
Assembly 'Moq.Dapper' with identity 'Moq.Dapper, Version=1.0.3.0, Culture=neutral, PublicKeyToken=null' uses 'Moq, Version=4.12.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920' which has a higher version than referenced assembly 'Moq' with identity 'Moq, Version=4.7.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920'
I am trying to mock out a dependency that uses Dapper, and I want it to return null. Normally, when I am using Moq, I will cast the null as the return type, and it works. When I do that here, I am getting a System.NullReferenceException
.
The code is as follows:
[Fact]
public async Task Test1()
{
Mock<IDbConnection> connection = new Mock<IDbConnection>();
connection
.SetupDapperAsync(m => m.QueryAsync<SampleTable>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync((IEnumerable<SampleTable>)null);
var actual = connection.Object.QueryAsync<SampleTable>("").GetAwaiter().GetResult().ToList();
}
The exception returned is:
Message: System.NullReferenceException : Object reference not set to an instance of an object. Stack Trace: DbDataReaderFactory.DbDataReader[TResult](Func
1 result)
<>c__DisplayClass2_01.<SetupQueryAsync>b__1() <>c__DisplayClass2_0
2.b__1()
--- End of stack trace from previous location where exception was thrown ---
Extensions.InvokePreserveStack(Delegate del, Object[] args)
ReturnLazyValueResponse.RespondTo(Invocation invocation)
MethodCall.Execute(Invocation invocation)
FindAndExecuteMatchingSetup.Handle(Invocation invocation, Mock mock)
IInterceptor.Intercept(Invocation invocation)
Interceptor.Intercept(IInvocation invocation)
AbstractInvocation.Proceed()
DbCommandProxy.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
SqlMapper.QueryAsync[T](IDbConnection cnn, Type effectiveType, CommandDefinition command) line 419
TableDomainTests.Test1() line 148
--- End of stack trace from previous location where exception was thrown ---`
I do have a workaround. In place of returning a null, I return an empty List
and it does work.
[Fact]
public async Task Test1()
{
Mock<IDbConnection> connection = new Mock<IDbConnection>();
connection
.SetupDapperAsync(m => m.QueryAsync<SampleTable>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(new List<SampleTable>());
var actual = connection.Object.QueryAsync<SampleTable>("").GetAwaiter().GetResult().ToList();
}
I just wanted to bring it to your attention.
Hi All.
I am currently using Dapper in my .net application but unable to make Unit Test for Dapper when I am currently using stored procedure not inline queries.
Please help me for same.
Dapper throws a NullReferenceException
when parameters are used in a command.
Given the following test scenario, the exception occurs:
[Test]
public void ExecuteScalar()
{
var connection = new Mock<IDbConnection>();
const int expected = 77;
connection.SetupDapper(c => c.ExecuteScalar<int>(It.IsAny<string>(), It.IsAny<object>(), null, null, null))
.Returns(expected);
var actual = connection.Object.ExecuteScalar<int>(
"select * from people where id = @id", new { id = 1 }, null, null);
Assert.That(actual, Is.EqualTo(expected));
}
Stack trace:
at ParamInfo44e2be98-d8bb-4358-8537-1dc2da8dc716(IDbCommand , Object )
at Dapper.CommandDefinition.SetupCommand(IDbConnection cnn, Action`2 paramReader)
at Dapper.SqlMapper.ExecuteScalarImpl[T](IDbConnection cnn, CommandDefinition& command)
at Dapper.SqlMapper.ExecuteScalar[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable`1 commandTimeout, Nullable`1 commandType)
When no parameters are used in the command, it works.
After investigation I found this
It turns out that Dapper internally needs to add parameters to the IDbCommand.Parameters
collection and this is currently null.
Hopefully the title is self explanatory. When using Moq.Dapper with QueryAsync an exception is thrown as it's not supported.
I have had a go at creating a PR for this but without much luck.
If you can give me an idea as to how you would approach it I can have another go.
Currently there is no support for Dynamic Parameters. Dapper uses a different code path for this object type over the anonymous object type. Additionally, it uses an outputCallback to fill in any parameters that are output types. Because there is no persistent mock for non-templated variables, each time Dapper tries to append a parameter to the query, it gets a new Parameters collection instead, causing an NRE. This needs to be solved for.
Hi,
I am experiencing unexpected behaviour when using the non generic SetupDapperAsync method. I was following the last example form the readme (which is an example for generic setup) and it is working fine. If I correct the test as in the example below the actual variable holds empty list.
[Fact]
public async Task QueryAsync()
{
// given
var connection = new Mock<IDbConnection>();
var expected = new[] { new { Id = 1, Name = "test1" }, new { Id = 2, Name = "test2" } };
connection.SetupDapperAsync(c => c.QueryAsync(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(expected);
// when
var actual = (await connection.Object.QueryAsync(string.Empty, null, null, null, null)).ToList();
// then
Assert.NotEmpty(actual);
}
Is it an issue or there is something wrong with my code?
I've added unit tests to demonstrate what I mean in a fork at https://github.com/Kintar/Moq.Dapper.
Basically, this prevents randomized results in queries and adjusting results based on number of executions or query parameters.
I don't understand Moq well enough to fix this myself (yet), so I thought I'd open an issue so that others can look into it as I try and educate myself enough to fix it.
I've got complex objects which have nullable types (ie int?
, DateTimeOffSet?
). The Moq.Dapper extension for QueryAsync seems to set these all to null instead of their value. I attempted a PR to fix this because I noticed you are restricting the types to non-null types. Adding nullable types just throws an exception in Dapper though.
Any ideas?
This is not an issue, but I thought you'd be interested to know this exists. If there is a better way to send such messages, I'd be glad to change my method.
I saw Entity Framework had similar code as this, but licensed differently. I took their code and created a library from it.
https://github.com/jhgoodwin/FakeDbProvider
I hope it's not seen as self promoting, because I did very little to it, other than add a build, publish a nuget package, fill in a few missing methods, then add one simple base class to use for creating tests.
Did not try it yet, but, you should be able to use this fake provider as a base for dapper, without issues.
John
code
var userPermissions = new RaPermission[0];
var user = new RaUser()
{
UserId = 1,
UserEmail = "UserEmail",
Permissions = userPermissions.ToList()
};
dbMock.SetupDapper(x => x.QueryFirstOrDefault<RaUser>(It.IsAny<string>(), It.IsAny<object>(), null, null, null))
.Returns(user);
stack trace
at Moq.Dapper.DbConnectionInterfaceMockExtensions.SetupDapper[TResult](Mock`1 mock, Expression`1 expression)
at RAPMD.Web.Tests.Auth.UserServiceTests.GetByIdExistsUserTest() in D:\EPAM\RAPMD\source\RAPMD.Web.Tests\Auth\UserServiceTests.cs:line 59
I suggest instead of coding up mock methods for every permutation of what is needed that a resolver system be added.
The idea works like this:
One possible such implementation would be a resource driven resolver. Store the queries, the parameter values, then resolve those to query outputs. If no query can be resolved, the resource resolver should tell the user that the resources do not contain the query/parameter combination, and how to fix it. Then, the answer to mocking would be to put in known query results for known query inputs. In a later date, if you change the query, or inputs, the match will be broken allowing you to take action to fix it.
Thoughts?
I was looking to work on such an idea and wondered if you would be interested in adding it to your repo if I did a PR.
I get an exception when I try to mock the ExecuteAsync method with StoredProcedure as command type.
var connection = new Mock<DbConnection>();
connection.SetupDapperAsync(c => c.ExecuteAsync(It.IsAny<string>(), It.IsAny<int>(), null, null, null)).ReturnsAsync(10);
var result = await connection.Object.ExecuteAsync("sp_test", new { Id = 1 }, null, null, CommandType.StoredProcedure);
Result StackTrace:
at ParamInfod786c014-bcd9-49cd-880d-6da8aec447ab(IDbCommand , Object )
at Dapper.CommandDefinition.SetupCommand(IDbConnection cnn, Action`2 paramReader)
at Dapper.SqlMapper.TrySetupAsyncCommand(CommandDefinition command, IDbConnection cnn, Action`2 paramReader)
at Dapper.SqlMapper.ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, Object param)
at ConsoleApp1.MyTests.DoTest()
--- End of stack trace from previous location where exception was thrown ---
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.
Apparently, it seems that the 'DbParameterCollection' property and the 'CreateDbParameter' method are not mocked, so we get an exception when dapper try to access the Parameter property.
If I mock them in the function DbConnectionMockExtensions.SetupNonQueryCommandAsync by adding the following code, I can run my test without error.
var commandMock = new Mock<DbCommand>();
commandMock.Protected()
.SetupGet<DbParameterCollection>(nameof(DbParameterCollection))
.Returns(new Mock<DbParameterCollection>().Object);
commandMock.Protected()
.Setup<DbParameter>("CreateDbParameter")
.Returns(new Mock<DbParameter>().Object);
mockResult(commandMock, () => result);
Should I add the code and submit a PR ?
So I have an object like this:
public class CptExtension
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public DateTime EffectiveDate { get; set; }
public DateTime? RetireDate { get; set; }
public CodeClassification? CodeClassification { get; set; }
public IList<EdsModifier> DisallowedModifiers { get; set; } = new List<EdsModifier>();
public Subcategory? SubCategory { get; set; }
public ContrastSetting? ContrastSetting { get; set; }
public BusinessUsage? BusinessUsage { get; set; }
public FamilyIndicator? FamilyIndicator { get; set; }
public MultiProcCode? MultiProcCode { get; set; }
}
I have setup my mapping with this:
public void SetupDapperCalls(int? id = null, string code = null, object model = null)
{
if (id.HasValue)
{
DbConnection.SetupDapperAsync(c => c.QueryAsync<CptExtension>(It.IsAny<string>(), null, null, null, CommandType.StoredProcedure))
.ReturnsAsync(CptExtensions.Where(x => x.Id == id.Value));
return;
}
if (!string.IsNullOrWhiteSpace(code))
{
DbConnection.SetupDapperAsync(c =>
c.QueryAsync<CptExtension>(It.IsAny<string>(), null, null, null, CommandType.StoredProcedure))
.ReturnsAsync(CptExtensions.Where(x => x.Code.Equals(code, StringComparison.OrdinalIgnoreCase)));
return;
}
if (model != null)
{
return;
}
DbConnection.SetupDapperAsync(c =>
c.QueryAsync<CptExtension>(It.IsAny<string>(), null, null, null, CommandType.StoredProcedure))
.ReturnsAsync(CptExtensions);
}
When the test call is made, the nullable enum types all return null. So my subsequent query integrity checks all fail, since the data is corrupted in transit. Now I know this is the fault of the mapping, but it shouldn't be there at all, my expected values should be unaltered as a result of the mock mapping. So, any ideas?
`var results = await connection.QueryAsync(
"[dbo].[GetSomething]",
types: new[]
{
typeof(Something),
typeof(ASubThing),
typeof(AnotherSubThing)
},
map: objects =>
{
var result = objects[0] as Something?? new Something();
result.FirstSubThing= objects[1] as ASubThing?? new ASubThing();
result.SecondSubThing= objects[2] as AnotherSubThing?? new AnotherSubThing();
return result;
},
dbArgs,
commandType: CommandType.StoredProcedure);`
moq.dapper continues to give an error saying that (When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id (Parameter 'splitOn') even though the code works fine when the api is running.
See #22
The following code causes a SystemNotSupportedException:
var mockDbConn = new Mock<IDbConnection>();
mockDbConn.SetupDapperAsync(x => x.ExecuteAsync(It.IsAny<string>(),
It.IsAny<object>(),
It.IsAny<IDbTransaction>(),
It.IsAny<int?>(),
It.IsAny<CommandType?>())
).ReturnsAsync(1);
Not sure what is causing the issue. Any suggestions?
I'm using Moq.Dapper for my unit tests, however when i used with parameter, throw exception "Object reference not set to an instance of an object"
Example:
var connection = new Mock<DbConnection>();
connection.SetupDapperAsync(c => c.ExecuteAsync(It.IsAny<string>(), It.IsAny<UsuarioInfo>(), It.IsAny<DbTransaction>(), null, null)).ReturnsAsync(0);
await connection.Object.ExecuteAsync("@Login", new { Login = "test"}, null);
Can you help me?
Hi,
when I try mock ExecuteScalarAsync method in IDbConnection
mock
[Fact()]
public async Task ExecuteScalarAsyncTest()
{
var connection = new Mock<IDbConnection>();
const string expected = "Hello";
connection.SetupDapperAsync(c => c.ExecuteScalarAsync<object>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(expected);
var actual = await connection.Object.ExecuteScalarAsync<object>("");
Assert.Equal(actual, expected);
}
the code throws following excpetion
Message:
System.NotSupportedException : Specified method is not supported.
Stack Trace:
DbConnectionInterfaceMockExtensions.SetupDapperAsync[TResult](Mock`1 mock, Expression`1 expression)
but when I change mock object to DbConnection
[Fact()]
public async Task ExecuteScalarAsyncTest()
{
var connection = new Mock<DbConnection>();
const string expected = "Hello";
connection.SetupDapperAsync(c => c.ExecuteScalarAsync<object>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(expected);
var actual = await connection.Object.ExecuteScalarAsync<object>("");
Assert.Equal(actual, expected);
}
the code works. For QueryAsync
both solution works without exceptions.
[Fact()]
public async Task ExecuteScalarAsyncTest()
{
var connection = new Mock<IDbConnection>();
string[] expected = new [] { "Hello" };
connection.SetupDapperAsync(c => c.QueryAsync<string>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(expected);
var actual = await connection.Object.QueryAsync<string>("");
Assert.Equal(actual.Count(), expected.Count());
}
If I need to use the same IDBConnection to make sequential calls within the scope of a given test, can one Mock object support multiple SetupDapper(db => db.Query()) calls. It appears not.
Hi.
If ComplexType has BigInteger property we get incorrect actual result for it (always 0).
If my complex type has an enum in it - that will normally map to an INT/ENUM pairing in the database to POCO query -- this returns always a zero.
var expected = new[] {
new FancyObject{Desired="2", DeviceGUID = Guid.Parse(validGUID), Installed="1", ImageTypeID = ImageType.BODY_IMAGE},
new FancyObject{Desired="4", DeviceGUID = Guid.Parse(validGUID), Installed="3", ImageTypeID = ImageType.HEADER_IMAGE}
};
connection.SetupDapper(c => c.Query<FancyObject>(It.IsAny<string>(), null, null, true, null, null)).Returns(expected);
// using this, the "expected" object is returned, but the ENUM (ImageTypeID) is 0
Using that object above as a Returns -- the ImageTypeID (an enum in FancyObject, but an INT in DB -- returns 0 - always).
All the other fields return the right values -- just the ENUM conversion seems to fail - it's 0 when returning the expected.
var connection = new Mock<IDbConnection>();
var expected = new[]
{
new ComplexType { StringProperty = "String1", IntegerProperty = 7 }
};
connection.SetupDapper(c => c.Query<ComplexType>(It.IsAny<string>(), null, null, true, null, null)) .Returns(expected);
////actual will not null
var actual = connection.Object.Query<ComplexType>("", null, null, true, null, null);
////Now try moq Query with any new type
connection.SetupDapper(c => c.Query<NewTestType>(It.IsAny<string>(), null, null, true, null, null)) .Returns(new [] { new NewTestType()} );
////actual will be null
actual = connection.Object.Query<ComplexType>("", null, null, true, null, null)
I got an argument null error when i tried to use an array as an sql parameter
var ids = new[] {1, 2, 3};
var result = connection.Query<Model>("SELECT * FROM TABLE WHERE id in @IDS", new { IDS = ids });
Debuging dapper i found that `command.CommandText' is null on SqlMapper class, what is causing this
Sorry, my bad, it's only available for Net Standard 2.0.
I'm trying to install the latest version (1.0.0.4) using .Net 4.5 from Nuget, but I can't.
This is the error from Visual Studio Output.Error | ย | Could not install package 'Moq.Dapper 1.0.0.4'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
Thanks!
I have tried to attach a callback method to assert generated SQL sent.
connectionMock
.SetupDapperAsync(x => x.QueryAsync<Instant StartTime, long SecondCount)>(
It.IsAny<string>(),
It.IsAny<Parameters>(),
null, null, null))
.Callback(
(string sql, Parameters, IDbTransaction transaction, int? commandTimeOut, CommandType? commandType) =>
{
// Assert
})
.ReturnsAsync(new (Instant StartTime, long SecondCount)[0]);
I get the message System.NullReferenceException : Object reference not set to an instance of an object.
on the same line as connectionMock.SetupDapperAsync is called.
Is this supported ?
The other parts work, if I remove the .Callback function everything runs fine
I would like to mock a sql query that contains a NVARBINARY
column but properties with the type byte[]
are not mapped.
Great library, exactly what I was looking for.
However its only available for full .NET. Is there a plan in place to make it available for .NET core or .NET standard ?
Hi,
the example with object
in ExecuteScalarAsync
generic works well (xUnit version)
[Fact()]
public async Task ExecuteScalarAsyncTest()
{
var connection = new Mock<DbConnection>();
const string expected = "Hello";
connection.SetupDapperAsync(c => c.ExecuteScalarAsync<object>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(expected);
var actual = await connection.Object.ExecuteScalarAsync<object>("");
Assert.Equal(actual, expected);
}
but when I change object
to desired specific type, e.g. string
the test throws exception in SetupDapperAsyncMethod
[Fact()]
public async Task ExecuteScalarAsyncTest()
{
var connection = new Mock<DbConnection>();
const string expected = "Hello";
connection.SetupDapperAsync(c => c.ExecuteScalarAsync<string>(It.IsAny<string>(), null, null, null, null))
.ReturnsAsync(expected);
var actual = await connection.Object.ExecuteScalarAsync<string>("");
Assert.Equal(actual, expected);
}
with followed message
Message:
System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.ISetup`2Proxy' to type 'Moq.Language.Flow.ISetup`2[System.Data.Common.DbConnection,System.Threading.Tasks.Task`1[System.String]]'.
Stack Trace:
DbConnectionMockExtensions.SetupDapperAsync[TResult](Mock`1 mock, Expression`1 expression)
Can you compile the nuget package for .NETStandard 2.0 as well? Dapper itself is in .NETFramework 4.6.1
and .NETStandard 2.0, so I don't see why not.
Attempting to gather dependency information for package 'Moq.Dapper.1.0.3' with respect to project 'serviceTests', targeting '.NETFramework,Version=v4.5.2'
Gathering dependency information took 1.29 sec
Attempting to resolve dependencies for package 'Moq.Dapper.1.0.3' with DependencyBehavior 'Lowest'
Resolving dependency information took 0 ms
Resolving actions to install package 'Moq.Dapper.1.0.3'
Resolved actions to install package 'Moq.Dapper.1.0.3'
Retrieving package 'Moq.Dapper 1.0.3' from 'nuget.org'.
Install failed. Rolling back...
Package 'Moq.Dapper.1.0.3' does not exist in project 'serviceTests'
Package 'Moq.Dapper.1.0.3' does not exist in folder 'F:\Temp\testmywcfs1\packages'
Executing nuget actions took 466.93 ms
Install-Package : Could not install package 'Moq.Dapper 1.0.3'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5.2', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, co
ntact the package author.
At line:1 char:1
+ CategoryInfo : NotSpecified: (:) [Install-Package], Exception
+ FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
Time Elapsed: 00:00:02.2250492
I suggest you move the main unit tests to be dotnet core compatible and only move the DataContext code to exist outside as a Framework only and tests that rely on Framework. This will allow the main development to continue in dotnet core.
Hey, I am having some difficulty with one of my mocks. I want to do this:
var dbConnectionMock = new Mock<DbConnection>(MockBehavior.Loose);
dbConnectionMock.SetupDapperAsync(m =>
m.QueryAsync(It.IsAny<string>(), It.IsAny<object>(), null, null, CommandType.StoredProcedure))
.ReturnsAsync(new List<dynamic>()).Verifiable();
But when I do, I get NullReferenceException because somehow ReturnsAsync is returning null. I also can't do .Verifiable().ReturnsAsync(...)
because Verifiable
is void
. (This seems like it shouldn't be affected by Moq.Dapper
since this method is from the core library, but I can only reproduce this issue when using Moq.Dapper
)
I have been able to get it working like this:
var dbConnectionMock = new Mock<DbConnection>(MockBehavior.Loose);
var mock = dbConnectionMock.SetupDapperAsync(m =>
m.QueryAsync(It.IsAny<string>(), It.IsAny<object>(), null, null, CommandType.StoredProcedure));
mock.ReturnsAsync(new List<dynamic>());
mock.Verifiable();
But I'd rather not have to spread it out like that since usually the setup is chainable.
Any suggestions?
Am trying to mock the Dapper method to return the Exception but it actually returning 0 rows instead the exception.
Here is the sample code
mockConnection.SetupDapper(c => c.Query<Student>(It.IsAny<string>(), null, null, true, null, null))
.Throws<InvalidOperationException>();
mockDatabase.Setup(x => x.GetConnection()).Returns(mockConnection.Object);
var repository = new StudentRepository(mockDatabase.Object);
// Act
var actual = repository.Get();
It Should return a InvalidOperationException
but instead its returning zero rows from Query<Student>
When passing a collection of values to ExecuteAsync(), the integer value returned by ExecuteAsync() is a multiple of the value specified in the call to ReturnsAsync().
Below is a modified copy of the DapperExecuteAsyncTest unit test from the Moq.Dapper.Test project. The expected value of "result" is 3; instead, a value of 9 is received, and the test fails.
If the testData argument is omitted from the call to ExecuteAsync(), the value of "result" is 3 and the test passes.
This behavior is problematic when unit testing a function that passes a collection in a call to ExecuteAsync() while mocking DbConnection; The integer returned by ExecuteAsync() should match the value specified in the call to .ReturnsAsync().
[Test]
public void ExecuteAsync()
{
var connection = new Mock<DbConnection>();
var testData = new int [] { 7, 77, 777 };
connection.SetupDapperAsync(c => c.ExecuteAsync("", null, null, null, null))
.ReturnsAsync(testData.Length);
// Specifying **testData** as the second argument causes this test to fail.
var result = connection.Object
.ExecuteAsync("", testData)
.GetAwaiter()
.GetResult();
// The result should be 3; instead, a value of 9 is returned and this test fails.
Assert.That(result, Is.EqualTo(testData.Length));
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.