如何使用BDD下的case语句有效地进行单元测试?

时间:2011-03-04 18:09:04

标签: unit-testing bdd

我对单元测试比较陌生,并且因为我的测试代码的数量与我的生产代码相比这个事实而感到担心,因为我有一些case语句,其中对外部函数的某些调用被重复但有不同的参数,随后不同的结果。对于名为calculateDeltas的公共函数,我的问题是一些javascript伪代码(如果格式不正确,则道歉)。在下面的代码中,populateDeltas是一个私有函数,我通过calculateDeltas的测试间接测试。

我正在努力解决的问题如下:
1.我用4种不同的方式测试calculateDeltas来覆盖4个不同的分支 通过这种方式,我有效地测试了populateDeltas 3次。 populateDeltas的每个测试都有一些断言,这些测试实际上是用不同的参数重复3次。
我有一个想法是单独测试populateDeltas。在那种情况下,我现在不测试实现,更重要的是,如果我从未将其作为整个单元进行测试,那么如何知道整个函数calculateDeltas是否有效? 4.即使这是一个好主意,它如何简化我对calculateDeltas的测试?我认为我会以某种方式验证populateDeltas被调用。
5.在那种情况下,我如何验证calculateDeltas的输出是否是我在调用的上下文中实际预期的结果?
6.换句话说,如何在不对私有函数运行集成测试的情况下知道calculateDeltas的工作原理? 7.这是否都违反了BDD的精神,即保护外部,而不是内部行为,而populateDeltas代表内部行为,而calculateDeltas代表外部行为?

感谢您的任何见解,我有点失落。代码如下:

function calculateDeltas(){
  var deltas = {status: this.rowStatus};
  switch(this.rowStatus){
    case 'new':
      this.populateDeltas(deltas, 'new');
      return deltas;
    case 'changed':
      deltas.key = this.key();
      this.populateDeltas(deltas, 'changed');
      return deltas;
    case 'unchanged':
      deltas.key = this.key();
      this.populateDeltas(deltas, 'unchanged');
      return deltas;
    case 'deleted':
      deltas.status = 'deleted';
      return deltas;
}

2 个答案:

答案 0 :(得分:0)

编写几个测试以涵盖所有场景没有任何问题。

如果您关心的是测试核心逻辑,那么case语句的一种方法是用策略模式替换条件逻辑。在这种情况下,我将有一个类来处理每个场景的逻辑,然后将它们放在查找表中。最终得到的代码只是根据行状态执行处理程序。您可以轻松地测试此逻辑一次,然后为每个处理程序编写特定的测试。

答案 1 :(得分:-1)

  

在下面的代码中,populateDeltas是一个私有函数,我通过calculateDeltas测试间接测试

这通常令人困惑。

重要的是要注意private不是必需的工具。公共职能很好。真。没有什么是私密的,Python人们非常高兴。我们都是成年人。

  

这是否都违反了BDD的精神,即保护外部,而不是内部行为,而populateDeltas代表内部行为,而calculateDeltas代表外部行为?

虽然BDD专注于外部行为,但您做出了实施决定创建私有共享功能。

您仍然可以执行BDD并测试此私有共享功能。只测试所有四个案例。外部接口依赖于此内部接口。

如果你想测试内部,那没关系。这不是BDD,这只是一个好主意。

有可能在BDD的好想法的最低基线之上有好的想法。由于您的实施选择,可以添加到BDD。

  

换句话说,如何在不对私有函数运行集成测试的情况下知道calculateDeltas的工作原理?

这是一个相当愚蠢的问题。想太多了。只需测试外部接口。如果外部函数使用内部私有函数,那么外部测试将在正常的事件过程中测试内部函数。