1

嘲笑に問題があります。クラス DistanceMatrix があり、どのメソッド form_matrix が if/else ステートメントで呼び出されたかを示したいと思います。mocha と RSpec を使用する必要があります。何か案は?

class DistanceMatrix

 def initialize(*args)
    if args[0].class == String
      form_matrix(get_data_from_yaml(args[0], args[1]))
    elsif args[0].class == Array || args[0] == nil
      form_matrix(get_data_from_db(args[0]))
    end
 end

 def form_matrix(...)
  ...
 end

end

それは試しました:

describe DistanceMatrix, "when mocking ..." do
  it "should do call form_matrix" do
    DistanceMatrix.any_instance.expects(:form_matrix).with([1]).once
    DistanceMatrix.any_instance.expects(:get_data_from_yaml).with("file_name.yml").once.returns([1])
    DistanceMatrix.new("file_name.yml")
  end
end

しかし、エラーが発生しました:

Failures:
  1) DistanceMatrix when mocking ... should do call form_matrix
     Failure/Error: DistanceMatrix.new("file_name.yml")
     unexpected invocation: #<AnyInstance:DistanceMatrix>.get_data_from_yaml('file_name.yml', nil)
     unsatisfied expectations:
     - expected exactly once, not yet invoked: #<AnyInstance:DistanceMatrix>.get_data_from_yaml('file_name.yml')
     - expected exactly once, not yet invoked: #<AnyInstance:DistanceMatrix>.form_matrix([1])
     satisfied expectations:
     - allowed any number of times, already invoked once: #<DistanceMatrix:0x9e48b40>.get_optimal_route(any_parameters)
     - allowed any number of times, already invoked once: #<Database::Distances:0x9d59798>.load_distances(any_parameters)
     # ./distance_matrix.rb:18:in `initialize'
     # ./tsp_algorithm_spec.rb:253:in `new'
     # ./tsp_algorithm_spec.rb:253:in `block (2 levels) in <top (required)>'
Finished in 0.25979 seconds

RSpec では .expects() ではなく .should_receive() を使用する必要があることがわかったので、次のことを試しました。

describe DistanceMatrix, "when mocking ..." do
  it "should do call form_matrix" do
    DistanceMatrix.any_instance.should_receive(:form_matrix).with([1])
    DistanceMatrix.any_instance.should_receive(:get_data_from_yaml).with("file_name.yml").and_return([1])
    DistanceMatrix.new("file_name.yml")
  end
end

しかし、新しい失敗がありました:

Failures:
  1) DistanceMatrix when mocking ... should do call form_matrix
     Failure/Error: DistanceMatrix.any_instance.should_receive(:form_matrix).with([1])
     (#<Mocha::ClassMethods::AnyInstance:0x96356b0>).form_matrix([1])
         expected: 1 time
         received: 0 times
     # ./tsp_algorithm_spec.rb:251:in `block (2 levels) in <top (required)>'

Finished in 0.26741 seconds
4

2 に答える 2

4

私はRSpecではなくMochaを使用した経験しかありませんが、Mochaの失敗メッセージを見ると、重要な部分は次のとおりです:-

unexpected invocation: #<AnyInstance:DistanceMatrix>.get_data_from_yaml('file_name.yml', nil)
unsatisfied expectations:
- expected exactly once, not yet invoked: #<AnyInstance:DistanceMatrix>.get_data_from_yaml('file_name.yml')

これらの行の最後を見るとget_data_from_yaml、 が期待されるパラメーターで呼び出されていないことがわかります。('filename.yml', nil)期待どおりではなく、で呼び出されて('filename.yml')います。

これは、引数を1 つDistanceMatrix.new("file_name.yml")だけ指定してテストを呼び出すと、insideが呼び出されているために発生しています。DistanceMatrix#initialize DistanceMatrix#get_data_from_yaml(args[0], args[1])argsargs[1]nil

これは Ruby の動作を期待したものではないかもしれませんが、以下はこの動作を示しています:-

def foo(*args)
  puts "args[0]=#{args[0].inspect}; args[1]=#{args[1].inspect}"
end

foo("string") # => args[0]="string"; args[1]=nil
于 2010-12-04T17:26:33.227 に答える
0
DistanceMatrix.any_instance.expects(:form_matrix).with("String") # => supply the correct string param

また

DistanceMatrix.any_instance.expects(:form_matrix).with([]) # => supply the correct array param

get_data_from_db および get_data_from_yaml メソッドが何を行っているかはわかりませんが、これらの入力を制御して、正しい引数が form_matrix に提供されていることを確認できるはずです。

EDITED イニシャライザで何かをモックしようとしているため、インスタンス変数をモックする代わりに DistanceMatrix.any_instance を使用する必要があります。また、不明な場合は、上記の行でモックを設定した後、実際に適切なメソッド呼び出しを行う必要があります。

DistanceMatrix.new("SomeString")

編集済み

it "should do call #form_matrix with proper arguments" do
  DistanceMatrix.any_instance.expects(:form_matrix).with([1])
  DistanceMatrix.any_instance.expects(:get_data_from_yaml).with("foo").returns([1])
  DistanceMatrix.new("foo")
end
于 2010-12-01T19:06:48.130 に答える