2010-12-01 2 views
1

나는 조롱하는 데 문제가 있습니다. 나는 DistanceMatrix 클래스를 가지고 있으며 은/else 문에서 form_matrix가 호출 된 메서드를 나타내기를 원합니다. 모카와 RSpec을 사용해야합니다. 어떤 아이디어?루비. 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 

하지만 오류가있어 : 나는 RSpec에 우리가하지 .expects를 사용하는 것을 발견

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 

()하지만 .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 
+0

#should_receive이 RSpec에의 조롱을 사용 - 원래는 모카를 사용하고있다. 모카를 사용하려면 프로젝트의 spec_helper.rb에서 구성해야합니다. – karmajunkie

+0

그 두 가지 오류는 form_matrix가 예상대로 호출되지 않았다는 것을 알려줍니다. 나는 그 문제가 당신의 시험에 있다고 생각하지 않습니다.내 생각 엔 당신이 이니셜 라이저에 전달하는 것은 줄 바꿈 된 문자열 또는 다른 것이므로 args [0] .class! = String입니다. 무슨 일이 일어나고 있는지 디버거에서 확인해 봤어? – karmajunkie

+0

아니요, 어떻게 리눅스 터미널에서 디버깅 할 수 있습니까? – Martynas

답변

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에 제공됩니다.

당신 대신 당신이 초기화에 뭔가를 조롱하기 위해 노력하고 있기 때문에 인스턴스 변수에 조롱의 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 
+0

내 두 get_data_from_yaml 및 get_data_from_db 배열 반환합니다. (: form_matrix) .with을 (an_instance_of (배열을 "...해야한다" distance_matrix = DistanceMatrix.any_instance distance_matrix = 모의 distance_matrix.expects을 을 "... 조롱 할 때" DistanceMatrix을 설명 :이 시도)) DistanceMatrix.new ("file_name.yml", [1, 2, 3]) 끝 끝 하지만 작동하지 않습니다. – Martynas

+0

좋아, 그 경우에는 get_data_from_yaml 및 get_data_from_db 메소드를 조롱하여 두 개의 알려진 값을 반환하고 알려진 값에 대한 기대치를 설정합니다. 위 편집을 참조하십시오. – karmajunkie

+0

시도했지만 실패했습니다. – Martynas

3

난 단지 모카하지 RSpec에를 사용하지만, 모카 실패 메시지를보고 경험을 가지고, 핵심 부품이 있습니다 편집 : -

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')이 호출되었습니다.

인수 테스트에 DistanceMatrix.new("file_name.yml")를 호출 한 후 내부 DistanceMatrix#initializeDistanceMatrix#get_data_from_yaml(args[0], args[1]) 호출되고 있으며 args는 단일 요소 배열이기 때문에, args[1]nil 될 때이 때문에 일어나고있다.

은 어쩌면 이것은 당신이 일을 루비를 예상되지 방법이지만, 다음은이 동작을 보여줍니다 : -

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

foo("string") # => args[0]="string"; args[1]=nil