【问题标题】:Questions about TDD关于TDD的问题
【发布时间】:2011-10-08 00:31:18
【问题描述】:

环境

在我的解决方案中,我有三个项目,它们是:

  1. Web (Asp.net MVC4)
  2. 模型(类库)
  3. 测试(测试项目)

模型项目中有:

Couple = 类

IRepository = 基于接口的存储库

ICoupleRepository = 接口存储库对

Implementationrepository = CoupleRepository 夫妇

测试项目中有:

Fake/CoupleRepository = 存储库对的假实现(在 Fake 文件夹内)。 CoupleTest 夫妇 class= 测试

行为

通过在下面添加一对,需要修改一些属性,同时添加一对对象也将其他对象添加到数据库中。

我将此逻辑放入Add方法中的CoupleRepository(不是假的)存储库中,设置这些属性,添加对象对和另外两个对象。

public class CoupleRepository : ICoupleRepository
{
    public void Add(Couple couple)
    {
        couple.Bride.Gender = Gender.Female;
        couple.Groom.Gender = Gender.Male;
        db.Couples.Add(couple);

        db.Users.Add(new User{ CoupleID = couple.Bride.ID });
        db.Users.Add(new User{ CoupleID = couple.Groom.ID });
        db.SaveChanges();

    }
}

问题

在我的测试类CoupleTest中,也需要测试这些用户的添加,以及属性的修改。

为我的额头创建一个假存储库对我没有帮助,真的需要测试默认 CoupleRepository 中的代码。

你给我的小费是什么

Mocks 和 Stubs 在这一切中都来自哪里?

这种逻辑会在哪里拯救一对夫妇?

我必须测试存储库?或许理想的方式是测试控制器?

很多问题,我知道 =)


我是 TDD 新手,不知道我的方向是否正确。

测试默认存储库并不理想,因为它访问数据库。

【问题讨论】:

  • 如果它实际上是 TDD,你不会先写单元测试吗?
  • 认为你的假实现是你的模拟。你只是没有这么称呼他们。然而,要成为真正有用的模拟,您需要能够告诉它们以某些方式表现,以便您可以测试不同的行为。
  • @DavidWick 是的,你说的。如果他没有从测试开始,那么他根本就没有进行测试驱动开发。
  • 事实上这是唯一的实现。我知道我做错了,但不知道从哪里开始测试。问题是在哪里放置这个实现以及如何测试它?

标签: asp.net-mvc-3 unit-testing architecture tdd mocking


【解决方案1】:

这里的主要问题是你混合了不同的层。存储库是业务逻辑和存储之间的中间层。如果您的情况,存储库执行作为业务逻辑一部分的操作。这就是为什么你不得不在测试中模仿它。

一般而言,您的实体应在保存之前完全构建。存储库应该只保存它(如果需要,可能调用 Validate 方法)。

这段代码:

couple.Bride.Gender = Gender.Female;
couple.Groom.Gender = Gender.Male;

应移至耦合业务逻辑(例如构造函数)。

从更全局的角度来看,通过 TDD,您可以围绕您想要测试的功能进行模拟。使用您当前的方法,您可能会有类似IView -> Couple class -> IRepository 链的东西。这意味着通过模拟这些接口,您打算测试 Couple 类(或一般的业务逻辑工作)。

要测试存储库,您需要一个类似Couple class -> CoupleRepository -> IDatabaseDriver 序列的结构。通过模拟IDatabaseDriver,您将能够验证由 CoupleRepository 的实际实现生成的 SqlCommands 或 Queries。

在这种情况下,您将编写如下测试(非常简单的示例):

var driver = new  MockDatabaseDriver();
var repo = CoupleRepository(MockDatabaseDriver);
repo.Add(new Couple());
Assert.AreEquals("Insert into COUPLES values ('bride', groom')", driver.SqlQueryText);

这里的 MockDatabaseDriver 不执行查询,只是指示存储库执行的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多