2012-02-27 44 views
1

我遇到了RSpec(2.8.0)自定义匹配器功能中的一些计数器直观行为,我不知道它是一个错误还是功能还是我很困惑。让我们来看看代码:RSpec自定义匹配器保持规范之间的状态

# matcher code 
RSpec::Matchers.define :exist do 
    chain :with_start_time do |time| 
    @start_time = time 
    end 

    chain :with_end_time do |time| 
    @end_time = time 
    end 

    match do |subject| 
    result = true 
    result &&= subject.start_time == @start_time if @start_time 
    result &&= subject.end_time == @end_time if @end_time 
    result 
    end 

    failure_message_for_should do |subject| 
    "Failure!\n".tap do |msg| 
     if @start_time != subject.start_time 
     msg << "Expected start_time to be #@start_time but was #{subject.start_time}\n" 
     end 
     if @end_time != subject.end_time 
     msg << "Expected end_time to be #@end_time but was #{subject.end_time}\n" 
     end 
    end 
    end 
end 

#spec code 
require 'ostruct' 

describe 'RSpec custom matcher keeping state between tests' do 
    let(:time) { Time.now } 

    it 'passes the first spec' do 
    o = OpenStruct.new(start_time: time) 
    o.should exist.with_start_time(time) 
    end 

    it 'fails the second because matcher kept @start_time from the first test' do 
    o = OpenStruct.new(end_time: time) 
    o.should exist.with_end_time(time) 
    end 
end 

这失败(演示该问题):

avetia01:~/projects/custom_matcher_bug% rspec test_spec.rb    
.F 

Failures: 

    1) RSpec custom matcher keeping state between tests fails the second because matcher kept @start_time from the first test 
    Failure/Error: o.should exist.with_end_time(time) 
     Failure! 
     Expected start_time to be 2012-02-27 12:20:25 +0000 but was 
    # ./test_spec.rb:41:in `block (2 levels) in <top (required)>' 

Finished in 0.00116 seconds 

2 examples, 1 failure 


所以意外的一点是,同样的匹配情况似乎在多个规格使用。在这种情况下,导致@start_time被初始化为第一个规格的值,从而导致第二个规格的错误失败。

回答

相关问题