关于 TDD 的问题
环境
在我的解决方案中,我有三个项目,它们是:
- Web (Asp.net MVC4)
- 模型(类库)
- 测试(测试项目)
在 模型项目 中有:
Couple
=类
IRepository
= 基于接口的存储库
ICoupleRepository
= 接口存储库对
Implementation
存储库 = CoupleRepository
对 在测试项目中有:
Fake/CoupleRepository
= 存储库对的假实现(在 Fake 文件夹内)。 CoupleTest
Couple class = Test
Behaviour
通过添加情侣,需要修改一些属性并且同时添加情侣对象同时添加其他对象到数据库中。
我将此逻辑放入 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 中的代码。
你给我的小费是什么?
模拟和存根在这一切中出现?
这个逻辑会在哪里保存几个?
我必须测试存储库?也许理想的方法是测试控制器?
我知道有很多问题 =)
我是 TDD 新手,不知道我是否在朝着正确的方向前进。
测试默认存储库并不理想,因为它访问数据库。
Environment
In my solution I have three projects, they are:
- Web (Asp.net MVC4)
- Model (Class library)
- Test (Test project)
In Model project have:
Couple
= Class
IRepository
= Interface-based repository
ICoupleRepository
= Interface Repository couple
Implementation
repository = CoupleRepository couple
In Test project have:
Fake/CoupleRepository
= Fake implementation of Repository couple (inside the folder Fake).CoupleTest
couple class = Test
Behavior
By adding a couple under, need to modify some properties and also add a couple object also add other objects to the database.
I put this logic into the CoupleRepository
(not fake) repository in Add
method, I set these properties, add the object couple and two other objects.
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();
}
}
Question
In my test class, CoupleTest
, need to test the addition of these users as well, and the modification of the properties.
Create a fake repository for my forehead it will not help me, really need to test code that is in default CoupleRepository.
What is the tip you give me?
Where Mocks and Stubs come in all this?
Where would this logic to save a couple?
I have to test repositories? Perhaps the ideal would be to test the controllers?
Many questions, I know =)
I'm new to TDD and do not know if I'm going in the right direction.
Test the default repository would not be ideal, since it accesses the database.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的主要问题是混合不同的层。存储库是业务逻辑和存储之间的中间级别。如果您的情况如此,存储库执行属于业务逻辑一部分的操作。这就是为什么你被迫在测试中模仿这一点。
一般来说,您的实体应该在保存之前完全构建。存储库应该只保存它(如果需要的话,可能调用 Validate 方法)。
此代码:
应移至耦合业务逻辑(例如构造函数)。
从更全局的角度来看,使用 TDD,您可以围绕要测试的功能进行模拟。使用您当前的方法,您可能会得到类似
IView ->;情侣班-> IRepository
链。这意味着通过模拟这些接口,您打算测试 Couple 类(或一般的业务逻辑工作)。要测试存储库,您需要一个类似
Couple class -> > 的结构。 CoupleRepository-> IDatabaseDriver
序列。通过模拟IDatabaseDriver
,您将能够验证由CoupleRepository 的实际实现生成的SqlCommands 或查询。在这种情况下,您将编写如下测试(非常简单的示例):
这里 MockDatabaseDriver 不执行查询,仅指示存储库执行的操作。
Main issue here is that you mix different layers. Repository is a intermediate level between Business Logic and storage. If your case, repository performs actions which are the part of Business logic. That's why you're forced to mimic that in your tests.
In general your entity should be fully constructed prior to saving. Repository should only save it (probably, invoking Validate method, if you need that).
This code:
should be moved to Couple business logic (constructor, for example).
From the more global point of view, with TDD you make mocks around the functionality you want to test. With your current approach you'll probably have something like
IView -> Couple class -> IRepository
chain. That means that by mocking those interfaces, you intend to test Couple class (or business logic work in general).To test the repository, you need a structure like
Couple class -> CoupleRepository -> IDatabaseDriver
sequence. By mockingIDatabaseDriver
you'll be able to verify SqlCommands or Queries generated by real implementation of CoupleRepository.In that case you'll write tests like (very simplistic sample):
Here MockDatabaseDriver doesn't execute queries, just indicates actions performed by repository.