【发布时间】:2015-12-05 00:27:47
【问题描述】:
我是 TDD 和 ATDD 的新手,我正在寻求了解用户故事与其接受标准之间的联系。对于上下文,我正在用 C# 构建一个带有 MVC 前端的 3 层应用程序。
例如,假设我有以下用户故事:
为了确保正确输入容量数据 作为个人更新此数据 当输入的数据不符合我们的业务规则时,我想要反馈。
对我来说,分解并定义什么是“容量数据”以及管理它的业务规则是有意义的。
例如,它可能具有必须大于零的“机器数”属性。
我想要避免做的是测试框架——如果我正确地遵循,我想要做的是测试这个业务逻辑是否正确实现,即:
- 业务规则(“机器数必须大于零”等)已在代码库中正确实现。
- 如果违反了业务规则,则会提醒用户注意此错误。
我相信我可以通过验证控制器中的无效模型状态重定向到同一页面来测试规则 #2,例如——并且有很多这样的例子。
但是,这样做不需要在视图模型上添加装饰吗?最终这会从用户的角度实现业务规则吗? (因此满足#1?)
假设我有以下语句/单元测试:
[Test]
public void GivenCapacityModelWhenNumMachinesZeroOrLessThenModelShouldBeInvalid()
{
// Given
IValidatorThing validator = new ValidatorThing(); //What enforces the rule? Should this be a controller service? Or a decorator such as [Range(0.000001,1000000)]? Doesn't each require different testing methods?
var invalidModel = new CapacityModel(); // Or the viewmodel?
double zeroValue = 0.000001;
invalidModel.NumMachines = zeroValue;
// When
var modelIsValid = ValidatorThing.validateModel(invalidModel);
// Then
Assert.IsFalse(modelIsValid);
}
当然,上面的内容不会编译。为了简单起见,我暂时省略了任何特定的模拟或固定框架。所以,为了使这个测试至少可以编译(但仍然失败),我需要做出一些决定:
- CapacityModel 是否应该是视图模型?还是来自服务层的 DTO?还是 DAL 层中的元数据类?我可以实现其中任何一个并使测试通过...但我真正应该测试什么?
- “验证器”是否检查验证此模型属性的服务的行为?还是CapacityModel上的数据注释?同样,我应该在 3 层应用程序的上下文中真正测试什么?
需要考虑的一些事项: 我要知道的一件事是,数据库表将具有描述这些规则的约束——因此,这条规则的目的似乎实际上是为了将这些规则传达给使用该应用程序的任何人。在那种情况下,我是否可以安全地假设将规则出现在三个地方会违反 DRY:视图模型、数据实体和数据库表。
我们在数据库中设置这些规则的原因是,我们希望确保 DBA 需要处理记录时不会意外违反规则。但是,据我所知,没有一种很好的方法可以将这些 CONSTRAINT 规则转换为应用程序的 DAL ......所以我想他们需要在应用程序中至少重复一次,以便将它们传达给用户。
那么,如果我要编写一个单元测试来满足业务规则,我会不会只是为了确保规则反映数据库?另外,还要编写一个单元测试来确保向用户显示正确的消息?
您能提供的任何指导都会很棒。我想觉得我所做的决定是合理的,或者至少有一个更好地解决问题的替代方法的想法。
谢谢,
劳伦斯
编辑:
所以,最终我试图以集中方式管理应用程序中的验证,以便我可以分离关注点——即控制器只关心路由,视图模型只关心显示数据,验证器例如,只关心验证等...而不是在视图模型中进行验证。
我发现了一个非常有用的article,它帮助我掌握了如何使用现有的 MVC 基础架构来做到这一点。希望这将有助于其他人研究这些类型的场景。
【问题讨论】:
标签: c# asp.net-mvc agile