我通过我称之为“命令”的类运行我的所有操作。为了说明这一点,为了创建一个新用户,我将调用以下代码
new CreateUserCommand(unitOfWork).SetName("Username").SetPassword("Blah").Execute();
我现在正在考虑在这个系统中实现验证,以验证一些事情,比如密码有一定的长度,用户名不是数据库中的副本,等等。
为了处理这个问题,我正在考虑使用fluent验证,并为我想要的每种类型的实体验证实体创建一个验证类。例如,我将有一个类,如
public class NewUserValidation : ValidationFor<User>
{
public NewUserValidation()
{
// Validation Rules here
}
}
在它自己的类中创建验证的一个优点是,我可以对多个命令使用相同的验证规则(例如,编辑和创建公司可能使用相同的验证规则)。
现在,这些验证类中的每一个都有与它们相关联的单元测试。然而,我正试图弄清楚如何处理使用这些验证类的命令类的单元测试。
例如,在为命令类创建测试时,我是否会为该类的每个验证规则创建单独的测试(因此基本上重复了我计划对每个命令类使用相同验证类的验证类本身的所有单元测试)?这造成了大量的开销,特别是当我已经知道验证类可以工作时,这是因为它们需要单独的单元测试。
我看到的唯一其他选项是在包含验证类的命令中公开一个公共属性,然后单元测试命令的验证类是预期的验证类。但是,这个方法的问题在于,我需要设计一些方法来验证我的Execute()
方法是否实际运行了验证类(否则,无法知道是否没有运行验证)。
我仍然倾向于后一种测试方法,这只是为了减少开销,但我确实需要找到一个解决方案来检查验证是否实际运行。这会不会是一个不好的方式去做它,我会更好地选择以前的风格而不是?
编辑:为了回答下面的两个答案,验证将在Execute()
方法的内部使用,在Execute()
的实现中使用一个validator.Validate(entity)
调用。
虽然我不想违反and,但我看不到一种简单的方法来验证Execute()
1)默认使用正确的验证类,而2)实际上调用验证类的.validate(entity)
方法。
我可以通过在构造函数中实例化验证类来解决#1,并通过命令类的公共属性公开它,但我不知道如何在不重复单个验证单元测试的情况下正确地对第二个问题进行单元测试。
发布于 2011-03-21 18:22:46
您已经测试了验证器类的功能。因此,对这些命令类进行测试的唯一方法是,它们实际上使用了验证器。
由于您计划如何使用这些验证器并不明显,因此很难说这是如何做到的。复制每个命令的测试用例是最不有效的方法,但最终,它可能是测试验证器存在的唯一方法。
编辑:从您最近的添加,这看起来是一个完美的候选人使用模拟对象。
要测试Execute
方法,可以模拟验证器,并验证它们的validate
方法是否被调用。要测试命令结构,可以模拟命令对象,并检查是否将适当的验证器传递给它。
您可能需要查看这个问题 (stackoverflow.com)。不过,您可能需要修改您的设计,以便使用模拟框架。
编辑:还可以看看这个问题 (stackoverflow.com)。它似乎满足了您的需求。微软工具鼹鼠 (microsoft.com)看起来非常有趣。
发布于 2011-03-21 18:23:30
你几乎从来不想违反DRY,所以我认为重复每个引用类的单元测试是绝对错误的。我不太理解您对于验证Execute方法是否运行验证类的关注。这不应该是执行方法的单元测试吗?一旦您测试了它,为什么需要专门针对每种类型的验证类进行测试呢?
最后,我不知道为什么需要“测试命令的验证类是预期的验证类”。听起来像是在测试一个工厂,而不是实际的Command类。
我只测试命令类直接负责的单元测试。如果Command类创建了它引用的自己的验证类,那么我想您可以对它进行单元测试。但根据你提供的信息,这听起来不太对。
发布于 2011-03-22 00:26:04
如果我是您,我将创建,只创建一个validationFalingTest,其中执行一个包含无效数据的命令。
此测试允许命令具有工作验证。在我看来,验证类的正确实例在很大程度上是特定于实现的。
https://stackoverflow.com/questions/5385923
复制