1

我一直在尝试开始更多地测试我的代码,我想我会模仿一些由我的rails脚手架自动生成的测试的风格(我正在使用rspec和rails,但我的问题真的只是一般- tdd)。但是,这些方法非常基本,类似于做某事。然后如果 foo,做其他事情。我觉得一旦您通过在 if 中添加另外 2 个条件来变得更加复杂,事情就会开始螺旋式上升,并且您会得到到处都是嵌套的示例。这是我一直在做的一个例子,感觉像是矫枉过正。

首先方法

def maybe_blah(foo)
  if foo != nil && foos.find_by_id(foo.id) != nil
    blah unless bar?(foo)
  end
end

这个方法很简单,这就是我打算如何测试它

describe maybe_blah

  shared_examples "what happens when bad input is passed" do
    it "doesn't call bar?"...
    it "doesn't call blah"...
  end

  context "when foo is not nil"
    context "when foo is in foos"
      context "bar? returns true"
        it "doesn't call blah" do
           some code involving mocking bar? and blah 
        end
      end

      context "bar? returns false"
        it "does call blah" do
           some code involving mocking bar? and blah 
        end
      end
    end

    context "when foo is not in foos"
       include_examples "what happens when bad input is passed"
    end
  end

  context "when foo is nil"
     include_examples "what happens when bad input is passed"
  end
end

这明显比如果有所有设置和其他任何东西(测试 may_blah 真的像那样花了我 55 行)的测试将要短,所以你可以看到它似乎是如何失控的。有没有一种很好的方法来测试一种确实感觉有点矫枉过正的方法。

当您有 3 个要测试的条件时,我看不到有 3 层深嵌套的方法(至少不要重复自己更多),但似乎您需要这样做以确保您正在处理所有不同的情况。此外,为每个不同的错误输入测试失败结果似乎很愚蠢,但是您怎么知道您实际上在这些错误输入上失败了?

那么这只是矫枉过正吗?

4

1 回答 1

1

其实你的条件是一样的:

def maybe_blah(foo)
  if foo != nil && foos.find_by_id(foo.id) != nil && !bar?(foo)
    blah
  end
end

因此,您可以使用分解条件合并条件表达式技术将其提取到单独的方法中:

def maybe_blah(foo)
  blah if can_do_it?(foo)
end

def can_do_it?(foo)
  foo != nil && foos.find_by_id(foo.id) != nil && !bar?(foo)
end

之后,您可以分两次测试此方法contexts

describe '#maybe_blah' do
  context 'when can do' do
    # stub can_do_it? and returns true
    # stould receive :blah
  end

  context 'when cant do' do
    # stub can_do_it? and returns false
    # should not receive :blah
  end
end

并分别测试条件。

你可以省略!= nil

def can_do_it?(foo)
  foo && foos.find_by_id(foo.id) && !bar?(foo)
end
于 2013-05-01T06:02:47.407 回答