关于TDD的问题

时间:2011-10-08 00:31:19

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

环境

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

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

    Couple =等级

    IRepository =基于接口的存储库

    ICoupleRepository = Interface Repository couple

    Implementation repository = CoupleRepository couple

    测试项目中有:

    Fake / CoupleRepository = Repository couple的伪实现(在文件夹Fake中)。 CoupleTest情侣类=测试

    行为

    通过添加一对,需要修改一些属性并添加一个对象也将其他对象添加到数据库中。

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

    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中的代码。

    你给我的提示是什么?

    哪里有模拟和存根?

    这个逻辑可以保存一对吗?

    我必须测试存储库吗?也许理想的是测试控制器?

    很多问题,我知道=)


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

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

1 个答案:

答案 0 :(得分:0)

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

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

此代码:

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

应该转移到Couple业务逻辑(例如构造函数)。

从更全球化的角度来看,使用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不执行查询,只表示存储库执行的操作。