12

次のコードがあるとします。

class A
  def create_server
    options = {
      name: NameBuilder.new.build_name
    }
    do_some_operations(options)
  end
end

そのようなメソッドをテストするために、私は以下を使用していましたallow_any_instance_of:

it 'does operations' do
  allow_any_instance_of(NameBuilder).to receive(:build_name)
  # test body
end

しかし、ドキュメントでは、いくつかの理由から使用しないように勧めています。どのように回避しallow_any_instance_ofますか?私がたどり着いた解決策は 1 つだけです。

class A
  def create_server
    options = {
      name: builder.build_name
    }
    do_some_operations
  end

  private

  def builder
    NameBuilder.new
  end
end

しかし、このようなアプローチでは、コードはすぐにほとんど役に立たないメソッドでいっぱいになります (特に、記述されたクラスでさまざまなオブジェクトの構成を積極的に使用する場合)。

4

2 に答える 2

3

テストが難しい場合は、クラスの設計に問題があることを意味します。あなたの場合、クラス内の特定のクラスで特定のメソッド呼び出しをテストしているとき、次のようにテストしています:

allow_any_instance_of(NameBuilder).to receive(:build_name)

テストは、メソッドが内部でどのように実装されているかを正確に知っています。クラスはロジックをカプセル化して非表示にする必要があります。あなたは正反対のことをしています。

内部メソッド ロジックをテストするべきではありません。動作をテストするだけです。入力を与え、出力の正しさをテストします。

クラスでそのメソッド呼び出しを本当にテストしたい場合はNameBuilder、その依存関係を注入して、クラスをよりテストしやすくします。これも OOP の原則に従います。

class A
  def create_server(builder)
    do_some_operations(name: builder.build_name)
  end
end
于 2016-04-15T09:49:16.270 に答える