首先,我知道在单元测试中具有多种断言是不好的。

但有时您需要测试一些原子交易。作为简化的例子,让我们拍摄有帐户类的一些银行应用程序:

class Account 
  attr_accessor :balance

  def transfer(to_account, amount)
    self.balance -= amount
    to_account.balance += amount
    Audit.create(message: "Transferred #{amount} from #{self.number} to #{to_account.number}."
  end

end
. 在这种情况下,我想一起检查3件事:

  1. 源帐户余额由amount
  2. 减少
  3. 目的地帐户余额由amount增加
  4. 审计记录插入
  5. 测试@account.transfer方法的最佳方法是什么?

有帮助吗?

解决方案

在这种情况下,我想一起检查3件事:

我认为你真正想要的是在某些条件下描述这些东西的行为,从而确保行为符合您的规格。这可能意味着事情发生在一起;或者这可能意味着有些事情只发生在一套条件下,而不是其他东西,或者一个例外导致所有要滚回其原始状态的情况。

在一次测试中没有魔法可以在一次测试中进行所有断言,除了使事情更快。 除非您面临严重的表现罚款(正常发生在全堆栈测试中),否则每次测试使用一个断言会更好。

rspec使提取测试设置阶段直接提取,以便为每个示例重复它:

class Account 
  attr_accessor :balance

  def transfer(to_account, amount)
    self.debit!(amount)
    to_account.credit!(amount)
    Audit.create!(message: "Transferred #{amount} from #{self.number} to #{to_account.number}."
  rescue SomethingBadError
    # undo all of our hard work
  end

end

describe Account do
  context "when a transfer is made to another account" do
    let(:other_account} { other_account }
    context "and the subject account has sufficient funds" do
      subject { account_with_beaucoup_bucks }
      it "debits the subject account"
      it "credits the other account"
      it "creates an Audit entry"
    end
    context "and the subject account is overdrawn" do
      subject { overdrawn_account }
      it "does not debit the subject account"
      it "does not credit the other account"
      it "creates an Audit entry" # to show the attempted transfer failed
    end
  end
end
.

如果在“快乐路径”中的所有三个测试传递,那么它们都是“发生在一起”,因为初始系统状态在每种情况下都是相同的。

但您还需要确保在出现问题时确保发生,并且系统返回其原始状态。具有多个断言使得很容易看到这是预期的工作,并且当测试失败时,完全是如何它们失败。

其他提示

每个测试的多个断言并不总是一个糟糕的做法。如果多个断言验证了相同的行为,那么它没有问题。尝试在同一测试中验证多个行为时存在问题。 当然,每个测试都有多种断言有一些风险。其中一个是您可能意外地从先前的测试集中留下值,使以奇怪的方式使先前的测试失效。 此外,当一个断言为假时,其他留下的所有留下都不会被执行,这可能导致了解GOIN的困难。但是合理的,你可以有多个断言断言相同的行为,最好是短的,没有额外的设置。

在你带来的简单情况下,我会使用多个断言,因为它很简单。但当然它可以得到更多复杂的,如负面的余额,不同类型的账户和东西。然后将更好地使用不同的测试(优选地)断言。我会像这样组织:

  • 1测试当前帐户的行为(最简单的情况);
  • 1到每种不同的路径,方法可以具有(例外,负 平衡等);
  • 1以每种可能性测试审计;

  • 1测试当前to_account的行为(最简单的情况);

  • 1到每个不同的路径都可以具有。 (例外,消极 平衡等);
  • 1以每种可能性测试审计;

由于审计测试非常简单,不需要额外的设置,您也可以与帐户和to_account进行测试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top