我应该测试预计不会发生任何事情的情况

时间:2016-08-19 12:03:09

标签: java unit-testing

如果状态为SampleS,则可以删除P。我有这个测试:

@Test
public void canBeDeletedWhenStatusIsP() {
    Sample sample = new Sample();
    sample.setState("P");
    assertTrue(sample.canBeDeleted());
}

@Test
public void canBeDeletedWhenStatusIsS() {
    Sample sample = new Sample();
    sample.setState("S");
    assertTrue(sample.canBeDeleted());
}

我应该走得更远吗?如何删除样本 时,我该如何测试?例如:

@Test
public void cantBeDeletedWhenStatusINeitherPNorS() {
    Sample sample = new Sample();
    sample.setState("Z");
    assertFalse(sample.canBeDeleted());
}

这个测试有用吗?测试命名怎么样?这个逻辑会经受足够的考验吗?

3 个答案:

答案 0 :(得分:13)

SaintThread正在给你一个很好的“直接”答案。

但让我们退后一步。因为您在生产代码中做错了什么。最有可能的是,您的生产代码执行类似于表示样本状态的String的开关。不仅一次,而且在它提供的所有方法中。而且......这不是一个好的OO设计!

相反,你应该使用多态,如:

abstract class Sample {
  boolean canBeDeleted();
// ... probably other methods as well

和各种具体的子类,如

class ZSample extends Sample {
  @Override canBeDeleted() { return false; }
// ...

最后,你有

class SampleFactory {
  Sample createSampleFrom(String stateIdentifier) {
  // here you might switch over that string and return a corresponding object, for example of class ZSample

然后,您的测试归结为:

  1. 测试工厂;输入“Z”的示例,它返回ZSample
  2. 的实例
  3. 测试Sample的所有子类;例如,canBeDeleted()为ZSample
  4. 的实例返回false

    重点是:您的代码确实完成了FSM(有限状态机)的工作。然后不要在整个地方使用if / elses;相反,做OO的事情:创建一个显式的状态机。并且,免费奖励:这种方法还可以将您的Sample对象转换为不可变的东西;这通常比必须处理可以随时间改变状态的对象更好(例如,不变性对多线程问题有很大帮助)。

    免责声明:如果您的“Sample”类只是关于那一种方法,那么上述内容可能过度。但在任何其他情况下......也许退后一步,看看我的建议是否会为您的设计增添价值!

答案 1 :(得分:2)

在我看来,你应该测试一下:

<强> cantBeDeletedWithoutStatus

assertFalse(sample.canBeDeleted());

<强> cantBeDeletedWhenStatusIsInvalid

sample.setState("Z");
assertFalse(sample.canBeDeleted());

<强> cantBeDeletedWhenStatusIsToggledToInvalid

sample.setState("P");
sample.setState("Z");
assertFalse(sample.canBeDeleted());

<强> canBeDeletedWhenStatusIsToggledToS

sample.setState("Z");
sample.setState("S");
assertFalse(sample.canBeDeleted());

<强> canBeDeletedWhenStatusIsToggledToP

sample.setState("Z");
sample.setState("P");
assertFalse(sample.canBeDeleted());

请在评论中告诉我您的想法

答案 2 :(得分:1)

我们应该希望我们的测试是彻底的,因此他们可能会检测到许多类错误。所以简单的答案是肯定的,测试无操作案例。

您没有告诉的可能值是什么。让我们假设它们必须是大写的英文字母,给出26个州。您的问题基本上与“我应该有26个测试用例”相同。这很多,但并不令人望而却步。现在想象一个更复杂的情况,状态是一个int,所有int值都是可能的。彻底测试它们是不切实际的。怎么办?

当输入或初始状态很多时,处理测试的方法是使用等价分区。将输入或状态划分为多组输入和状态集,使得集合中的所有元素应该产生相同的行为并且彼此相邻。所以在你的情况下,等价分区可能是A-O,P,Q-R,S,T-Z。然后为每个分区都有一个测试用例。