C# 下面的场景如何通过单元测试进行测试?

C# 下面的场景如何通过单元测试进行测试?,c#,unit-testing,C#,Unit Testing,我会对以下内容进行单元测试还是进行其他类型的测试: 我想更新数据库中的一个值,在更新该值之后,我想确保数据库被更新为正确的值,但这意味着我必须查询数据库并确定是否存在正确的值,我认为在单元测试中,触摸数据库是不允许的 我想对如下方法进行单元测试(db和Update是由以下两部分组成的): 您可以简单地测试您的方法是否成功地调用了数据库。嘲弄倾向于关注这一点,即你期望发生的呼叫实际上确实发生了 它将涉及用测试版本替换db,这样您的UpdateValue测试将断言它期望使用相同的值调用db.Upda

我会对以下内容进行单元测试还是进行其他类型的测试:

我想更新数据库中的一个值,在更新该值之后,我想确保数据库被更新为正确的值,但这意味着我必须查询数据库并确定是否存在正确的值,我认为在单元测试中,触摸数据库是不允许的

我想对如下方法进行单元测试(db和Update是由以下两部分组成的):


您可以简单地测试您的方法是否成功地调用了数据库。嘲弄倾向于关注这一点,即你期望发生的呼叫实际上确实发生了

它将涉及用测试版本替换
db
,这样您的
UpdateValue
测试将断言它期望使用相同的值调用
db.Update(value)

测试存储过程或SQL应该完成(在一天结束时,它仍然会受到与C#代码相同的错误可能性的影响),但可能会独立于代码单元测试来完成。我们有一个单独的测试项目来测试存储过程逻辑。因为这涉及到一个物理数据库,所以它是独立的、最小的,但我们仍然认为它是必要的。我们已经到了测试几乎所有数据库脚本的阶段,但首先,您通常可以不测试基本的CRUD代码。任何以条件语句为特征的SQL都会得到测试

如果要执行端到端测试,以查看是否可以使用代码保存到数据库并再次获取值,则根据定义,这不是单元测试。这是一个集成测试。单元测试的目的是删除代码单元周围的所有依赖项,以便单独测试该单元

也就是说,(在我看来)也必须进行集成测试。我们针对用例使用它们,这样我们就可以测试用户作为用例操作签署的内容。这会一次性敲打大量代码,但有一个明显的缺点,就是与共享状态/副作用代码作斗争。您会发现,对于集成测试,大部分测试都是准备,而不是断言代码。您还发现,它们无法识别失败的特定代码,因此诊断集成测试失败更加困难


我们通过集成测试达成了一个折衷方案。我们的数据库是通过DAL接口提供的,我们只需将这个接口存根(与模拟不同),以提供内存中的测试数据,而不是物理数据库。这样做的一个缺点是我们错过了对数据库本身的集成测试。

您可以简单地测试您的方法是否成功地调用了数据库。嘲弄倾向于关注这一点,即你期望发生的呼叫实际上确实发生了

它将涉及用测试版本替换
db
,这样您的
UpdateValue
测试将断言它期望使用相同的值调用
db.Update(value)

测试存储过程或SQL应该完成(在一天结束时,它仍然会受到与C#代码相同的错误可能性的影响),但可能会独立于代码单元测试来完成。我们有一个单独的测试项目来测试存储过程逻辑。因为这涉及到一个物理数据库,所以它是独立的、最小的,但我们仍然认为它是必要的。我们已经到了测试几乎所有数据库脚本的阶段,但首先,您通常可以不测试基本的CRUD代码。任何以条件语句为特征的SQL都会得到测试

如果要执行端到端测试,以查看是否可以使用代码保存到数据库并再次获取值,则根据定义,这不是单元测试。这是一个集成测试。单元测试的目的是删除代码单元周围的所有依赖项,以便单独测试该单元

也就是说,(在我看来)也必须进行集成测试。我们针对用例使用它们,这样我们就可以测试用户作为用例操作签署的内容。这会一次性敲打大量代码,但有一个明显的缺点,就是与共享状态/副作用代码作斗争。您会发现,对于集成测试,大部分测试都是准备,而不是断言代码。您还发现,它们无法识别失败的特定代码,因此诊断集成测试失败更加困难


我们通过集成测试达成了一个折衷方案。我们的数据库是通过DAL接口提供的,我们只需将这个接口存根(与模拟不同),以提供内存中的测试数据,而不是物理数据库。这样做的一个缺点是我们错过了对数据库本身的集成测试。

对象的责任是将值传递给它的依赖项(即数据库)。因此,向对象注入一些表示数据库的抽象:

public Foo(IDatabase db)
{
   _db = db;
}
并验证此依赖项与正在测试的对象之间的交互:

Mock<IDatabase> db = new Mock<IDatabase>();
db.Setup(x => x.Update(5));
Foo foo = new Foo(db.Object);
foo.Update(5);
db.VerifyAll();
Mock db=new Mock();
db.Setup(x=>x.Update(5));
Foo-Foo=新的Foo(db.Object);
foo.Update(5);
db.VerifyAll();
您是对的,在单元测试中触摸数据库是不行的。单元测试应该只验证一个单元的行为(隔离)。若您想检查几个一起工作的单元(您的foo和db),那个么您需要一个集成测试来验证数据库中实际更改的数据


更新:此示例中使用了框架。

对象的职责是将值传递给其依赖项(即数据库)。因此,向对象注入一些表示数据库的抽象:

public Foo(IDatabase db)
{
   _db = db;
}
并验证此依赖项与正在测试的对象之间的交互:

Mock<IDatabase> db = new Mock<IDatabase>();
db.Setup(x => x.Update(5));
Foo foo = new Foo(db.Object);
foo.Update(5);
db.VerifyAll();
Mock db=new Mock();
db.Setup(x=>x.Update(5));
Foo-Foo=新的Foo(db.Object);
foo.Update(5);
db.VerifyAll();
您是对的,在单元测试中触摸数据库是不行的。单元测试应该验证