c# - “Mock” 数据库和 “Real” 数据库行为之间的差异

标签 c# database linq count mocking

我们将 C# 和 Linq2SQL 与 MS SQL Server 数据库结合使用。 我们有一个 mockdatacontext 来执行一些单元测试。 在测试时,我们发现了两种不同的行为,具体取决于使用的是“真实”数据库还是“模拟”数据库。

场景一:真实数据库

数据库中有5条记录:

db = realDatabase
db.InsertOnSubmit(new record)

var count1 = db.getTable.Count()

db.SubmitChanges()

var count2 = db.getTable.Count()

count1 = 5 count2 = 6

场景二:模拟数据库

数据库中有5条记录:

db= mockDatabase

db.InsertOnSubmit(new record)

var count1 = db.getTable.Count()

db.SubmitChanges()

var count2 = db.getTable.Count()

count1 = 6 count2 = 6

*“模拟”数据库在调用 SubmitChanges() 之前已经知道新记录,因此它包含在计数中。为了进行测试,我们需要两种行为相同。

有没有其他人遇到过这个问题,您能提出解决方案吗?

最佳答案

IMO,在测试中试图模拟是一个常见的错误。 mock 不是模拟器。它不应该实现与原始逻辑相似的逻辑,它应该只返回硬编码结果。

如果模拟行为很复杂,您最终会测试模拟而不是业务代码。

我正在使用 RhinoMocks,它看起来像这样:

// arrange
IList<Record> testdata = new List<Record>() {a, b, c};
db = MockRepository.GenerateMock<IDatabase>();
db.Stub(x => db.getTable).Return(testdata);

// act: call your unit under test

// assert
db.AssertWasCalled(x => x.InsertOnSubmit(Arg<Record>.Is.Anything));
db.AssertWasCalled(x => x.SubmitChanges());

它每次仍然返回相同的列表。对于许多情况,这就足够了。您仍然可以在第二个 getTable 调用中返回其他数据:

db.Stub(x => db.getTable).Return(testdata1);
db.Stub(x => db.getTable).Return(testdata2);

它总是特定于单个测试,但这使它变得如此简单。

编辑:

我不得不承认我不熟悉 Linq2Sql。在我的示例中模拟的调用是 Linq2Sql 调用,可能无法轻易模拟。您可能需要将其放在一个简单的 DAL 接口(interface)后面。然后你模拟这个接口(interface)。

关于c# - “Mock” 数据库和 “Real” 数据库行为之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/795204/

相关文章:

使用 MyISAM 和 InnoDB 表维护 MySQL 数据库

c# - Linq - 按数字然后按字母排序

c# - 使用 Where 条件给出空值的列表集合过滤

c# - ListItemCollection - 使用 LINQ 从值中获取文本

c# - 如何确定给定类型 (System.Type) 是否继承自特定基类(在 .Net 中)?

c# - C#中的强类型资源文件

c# - 使用 C# 实现 Excel 自动化

c# - Azure Web App 引发 HTTP 错误 500.0 - 内部服务器错误 由于发生内部服务器错误,无法显示页面

php - 带有 pdo 的基于文件的 php 数据库

c# - SQL - 更好的两个查询而不是一个大查询