- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写单元测试用例,并且成功地为 Query
编写了单元测试用例。但是我没有为 QueryMultiple
编写单元测试用例。
对于查询,我是这样写的:
IEnumerable<ClientTestPurpose> fakeTestPurposes = new
List<ClientTestPurpose>()
{
new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name1"},
new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name2"},
new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name3"}
};
_mock.SetupDapper(x => x.Query<ClientTestPurpose>(It.IsAny<string>(), null, null, true, null, null)).Returns(fakeTestPurposes);
var result = _libraryRepository.TestPurposes(clientModal.Id);
Assert.IsNotNull(result);
Assert.AreEqual(result.Count(), fakeTestPurposes.Count());
如何为QueryMultiple
编写:
using (var multi = _db.QueryMultiple(spName, spParams, commandType: CommandType.StoredProcedure))
{
var totals = multi.Read<dynamic>().FirstOrDefault();
var aggregates = multi.Read<StatusModel>();
var scripts = multi.Read<LibraryItemModel>();
var runs = multi.Read<RunSummaryModel>();
var filteredTotals = multi.Read<dynamic>().FirstOrDefault();
}
最佳答案
显然您使用了 Moq.Dapper 扩展。以下是 SetupDapper
和 SetupDapperAsync
方法的代码:
public static ISetup<IDbConnection, TResult> SetupDapper<TResult>(this Mock<IDbConnection> mock, Expression<Func<IDbConnection, TResult>> expression)
{
MethodCallExpression body = expression.Body as MethodCallExpression;
if ((body != null ? body.Method.DeclaringType : (Type) null) != typeof (SqlMapper))
throw new ArgumentException("Not a Dapper method.");
string name = body.Method.Name;
if (name == "Execute")
return (ISetup<IDbConnection, TResult>) DbConnectionInterfaceMockExtensions.SetupExecute(mock);
if (name == "ExecuteScalar")
return DbConnectionInterfaceMockExtensions.SetupExecuteScalar<TResult>(mock);
if (name == "Query" || name == "QueryFirstOrDefault")
return DbConnectionInterfaceMockExtensions.SetupQuery<TResult>(mock);
throw new NotSupportedException();
}
public static ISetup<IDbConnection, Task<TResult>> SetupDapperAsync<TResult>(this Mock<IDbConnection> mock, Expression<Func<IDbConnection, Task<TResult>>> expression)
{
MethodCallExpression body = expression.Body as MethodCallExpression;
if ((body != null ? body.Method.DeclaringType : (Type) null) != typeof (SqlMapper))
throw new ArgumentException("Not a Dapper method.");
if (body.Method.Name == "QueryAsync")
return DbConnectionInterfaceMockExtensions.SetupQueryAsync<TResult>(mock);
throw new NotSupportedException();
}
如您所见,Moq.Dapper 仅支持对 Execute
、ExecuteScalar
、Query
和 QueryAsync
方法进行模拟.因此,您可能会在尝试模拟 QueryMultiple
时遇到 NotSupportedException
。要模拟数据库行为,您可能需要首先引入另一个抽象级别,正如@TrueWill 在评论中所说。这只是您的情况下的想法示例:
[Test]
public void DoSomethingWithQueryTest()
{
// Arrange
IEnumerable<ClientTestPurpose> fakeTestPurposes = new
List<ClientTestPurpose>
{
new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name1" },
new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name2" },
new ClientTestPurpose { PurposeID = 1, PurposeName = "Test Purpose name3" }
};
var mock = new Mock<ILibraryRepository>();
mock.Setup(x => x.TestPurposes(It.IsAny<int>())).Returns(fakeTestPurposes);
var logicService = new SomeLogicService(mock.Object);
// Act
var result = logicService.DoSomethingWithQuery(1);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(result.Count(), fakeTestPurposes.Count());
}
[Test]
public void DoSomethingWithQueryMultipleTest()
{
// Arrange
SomeAggregate fakeTestPurposes = new SomeAggregate();
var mock = new Mock<ILibraryRepository>();
mock.Setup(x => x.TestQueryMultiple()).Returns(fakeTestPurposes);
var logicService = new SomeLogicService(mock.Object);
// Act
var result = logicService.DoSomethingWithQueryMultiple();
// Assert
Assert.IsNotNull(result);
}
public interface ILibraryRepository
{
IEnumerable<ClientTestPurpose> TestPurposes(int id);
SomeAggregate TestQueryMultiple();
}
public class LibraryRepository : ILibraryRepository
{
private readonly IDbConnection _db;
public LibraryRepository(IDbConnection db)
{
_db = db ?? throw new ArgumentNullException(nameof(db));
}
public IEnumerable<ClientTestPurpose> TestPurposes(int id)
{
return _db.Query<ClientTestPurpose>("SQL here", new { id }, null, true, null, null);
}
public SomeAggregate TestQueryMultiple()
{
string spName = "SQL here";
var spParams = new { Id = 1 };
using (var multi = _db.QueryMultiple(spName, spParams, commandType: CommandType.StoredProcedure))
{
return new SomeAggregate
{
totals = multi.Read<dynamic>().FirstOrDefault(),
aggregates = multi.Read<StatusModel>(),
scripts = multi.Read<LibraryItemModel>(),
runs = multi.Read<RunSummaryModel>(),
filteredTotals = multi.Read<dynamic>().FirstOrDefault()
};
}
}
}
public class SomeAggregate
{
public IEnumerable<dynamic> totals { get; set; }
public IEnumerable<StatusModel> aggregates { get; set; }
public IEnumerable<LibraryItemModel> scripts { get; set; }
public IEnumerable<RunSummaryModel> runs { get; set; }
public IEnumerable<dynamic> filteredTotals { get; set; }
}
/// <summary>
/// Example logic server, that just returns results from repository
/// </summary>
public class SomeLogicService
{
private readonly ILibraryRepository _repo;
public SomeLogicService(ILibraryRepository repo)
{
_repo = repo;
}
public IEnumerable<ClientTestPurpose> DoSomethingWithQuery(int id)
{
return _repo.TestPurposes(id);
}
public SomeAggregate DoSomethingWithQueryMultiple()
{
return _repo.TestQueryMultiple();
}
}
主要思想是将所有数据库特定的东西隐藏在 ILibraryRepository
后面,并将您需要测试的所有逻辑移动到某个逻辑服务器,该服务器将接收存储库作为依赖项。为了存储库中的代码应该简单、明显,包含所有 DB 特定逻辑:连接、事务、命令、对象关系映射等。并且您不需要用 unt 测试覆盖这些代码。然而,你确实用单元测试覆盖了 SomeLogicService
的代码,因为这是你真正需要测试的。你会看到 Dapper 扩展方法是相当低级的抽象,它没有隐藏使用 DB 的细节,它们只是帮助者。希望能帮助到你。
关于unit-testing - 如何使用 Moq.Dapper 模拟 QueryMultiple,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52414562/
有谁知道或有如何使用的链接https://github.com/henkmollema/Dapper-FluentMap在我的 Dapper CRUD 中?现在我正在使用 Dapper.Contrib
我正在寻找一种方法来仅更新 Dapper 中的设置属性。即仅当实体的属性不为空时才更新实体的属性。 我正在用一种相当粗糙的方法解决同样的问题,如下所示,但我相信应该有一种更简洁的方法来做到这一点。
方案: 我的模型中有一个字符串属性,其中包含MultiSelectList @Html.ListBox的ID。如果选择两个列表项,则我的属性值将类似于0100,0500。 问题: Dapper whe
我们正在使用 Dapper 进行一些数据访问事件,并使用标准推荐方法连接到数据库,如下所示: public static Func ConnectionFactory = () => new SqlC
是否可以通过表名 作为 Dapper Query 命令的参数?我不是在寻找 SQL 表定义的函数或 SQL 表变量。我想在 C# 中定义表名并将其传递给 Dapper。这是我的代码,执行时返回错误 M
我在dapper中尝试对包含NULL的列进行拆分时遇到MultiMaps问题。 Dapper似乎不实例化对象,并且我的映射函数接收null而不是对象。 这是我的新测试: class Produ
我似乎找不到我的问题的文档或示例(现在已经搜索了一段时间)。我认为我的问题很简单,所以这里是。 我有两张 table 。我的主表称为 Persons,辅助表是 PersonEntries。对于 Per
我的代码有点问题,我想让 dapper 很好地使用它。 当我说我的代码是继承的,所以这不是我的设计。 我正在尝试替换 Entity Framework,因为对数据库的调用效率不高,所以我想更好地控制生
我已经开始玩 Dapper.Net,到目前为止我真的很喜欢它 - 然而,我遇到了一个问题。 假设我有一个 POCO 类: public class Person { public string
我已经开始玩 Dapper.Net,到目前为止我真的很喜欢它 - 然而,我遇到了一个问题。 假设我有一个 POCO 类: public class Person { public string
我知道这是一种错误的做法,但我正在处理具有 NULLS 的遗留代码库,当它表示空字符串时,反之亦然。 我无法立即看到它是如何可能的,但是当从数据库映射回来时,是否有可能获取(或修改 dapper 以便
我正在尝试选择一个包含 2 个整数列的列表,将结果映射到一个元组。举个例子: return connection.Query>("select id1, id2 from sometable").To
我有一个存储过程,它有一个没有默认值的参数,但它可以为空。但我不知道如何使用 Dapper 传递 null。我可以在 ADO 中做得很好。 connection.Execute("spLMS_Upda
我决定使用 Dapper.net,因为它似乎只做我想做的事情:映射,我不需要任何花哨的东西,我只是厌倦了处理我的数据读取器和我的对象之间的映射。 我的问题: 假设我有这些类(class): class
我在从 Dapper 查询返回单个对象时遇到问题。我有一个简单的查询,我想从返回的集合中获取第一个对象。我错过了什么? using (SqlConnection sqlConnection = new
假设我的实体是 public class AppUser { string Id { get; set; } string Name { get; set; } } 看起来默认情况下
我在Dapper官方文档中看到了QueryMultiple,如下所示,很方便! var sql = @" select * from Customers where CustomerId =
我正在使用 Dapper 查询包含 XML 字段的表: CREATE TABLE Workflow ( Guid uniqueidentifier not null, State xm
我有一个来自Dapper查询的动态结果,其中包含如下记录: {DapperRow, billing_currency_code = 'USD', count(*) = '6'} 我可以使用rowVar
我正在使用 Dapper 扩展,但我的数据库中有多个架构名称。 我在下面的链接中找到了答案,但它假设我只有一个模式名称,这不是我的情况。 Dapper Extensions Change Schema
我是一名优秀的程序员,十分优秀!