在生产数据库(或用于测试的克隆)中定义属性后,这不是单元测试。单元测试检查工作单元,不需要特定的外部状态即可工作。假定Offer1
在数据库中将其定义为仅限男性的商品。那是外部状态。因此,这更多是集成测试,特别是系统测试或验收测试。请注意,验收测试通常没有编写脚本(不在测试框架中运行,而是由人类手动执行)。
当在域模型中使用if
语句定义属性时,同一测试就是单元测试。而且它可能很脆。但是真正的问题是代码很脆弱。通常,如果可配置而不是硬编码业务行为,则代码将更具弹性。因为急于部署以解决小的编码错误应该很少。但是,更改业务需求而不另行通知只是星期二(每周发生一次)。
您可能正在使用单元测试框架来运行测试。但是单元测试框架不仅限于运行单元测试。他们也可以并且确实运行集成测试。
如果你正在写一个单元测试,你就同时创建person
,并offer1
从一开始就对数据库状态没有依赖。就像是
[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
var personId = Guid.NewGuid();
var gender = "F";
var person = new Person(personId, gender);
var id = Guid.NewGuid();
var offer1 = new Offer1(id, "ReturnsFalseWhenGivenAPersonWithAGenderOfFemale");
offer1.markLimitedToGender("M");
Assert.False(offer1.IsEligible(person));
}
请注意,这不会根据业务逻辑而改变。并不是说offer1
拒绝女性。这是offer1
拒绝女性的一种提议。
您可以在测试中创建和配置数据库。在C#中,使用NUnit或在Java的JUnit中,您可以通过一种Setup
方法来设置数据库。大概您的测试框架具有类似的概念。在这种方法中,您可以使用SQL将记录插入数据库。
如果您很难编写用测试数据库代替生产数据库的代码,这听起来像是应用程序中的测试弱点。对于测试,最好使用诸如依赖注入之类的允许替换的东西。然后,您可以编写独立于当前业务规则的测试。
这样做的附带好处是,企业所有者(不一定是企业所有者,更像是企业层次结构中负责此产品的人员)通常更容易直接配置业务规则。因为如果您拥有这种技术框架,就很容易允许企业所有者使用用户界面(UI)来配置商品。企业所有者将在UI中选择限制,然后它将发出markLimitedToGender("M")
呼叫。然后,当要约持久化到数据库时,它将存储此内容。但是您不需要存储要使用的报价。因此,您的测试可以创建和配置数据库中不存在的商品。
在所描述的系统中,企业所有者必须向技术组提出请求,技术组将发出适当的SQL并更新测试。或者技术小组必须编辑您的代码和测试(或先测试,然后再编码)。这似乎是一个相当沉重的方法。你能行的。但是,如果您不必这样做的话,您的软件(而不仅仅是您的测试)将不会那么脆弱。
TL; DR:您可以编写这样的测试,但是最好不要编写软件,这样就不必这样做。