模拟具体实例

时间:2014-08-16 14:02:48

标签: ruby-on-rails-4 rspec

这是我正在测试的简单代码:

def inside
    @location = Location.find(params[:id])
    @locations = @location.inside
end

这是期望:

describe '#inside' do
    # objects
    let(:location){            FactoryGirl.create(:location, longitude: 5, latitude: 5, radius: 5) }
    let(:location_inside){     FactoryGirl.create(:location, longitude: 6, latitude: 5, radius: 1) }
    let(:location_not_inside){ FactoryGirl.create(:location, longitude: 10, latitude: 10, radius: 1) }

    # request
    let(:request){ get :inside, id: location.id }

    describe 'response' do
        before do
            location.should_receive(:inside).and_return([location_inside])
            request
        end

        specify{ expect( assigns :location).to eq location }

        specify{ expect( assigns :locations).to include location_inside }
        specify{ expect( assigns :locations).to_not include location_not_inside }
        specify{ expect( assigns :locations).to_not include location } # a bug I was getting
    end
end

如果我没有嘲笑location实例,它会完美传递。但是,我想嘲笑,但我不能,因为这种情况发生了:

Failure/Error: airspace_one.should_receive(:inside).and_return([location_inside])
       (#<Location:0x0000000325ddb8>).inside(any args)
           expected: 1 time with any arguments
           received: 0 times with any arguments

现在,很明显为什么会这样。我认为这是因为FactoryGirl创建的location是一个相同但独立的Location实例。那么我的意思是如何在我的代码库中模拟实例?我可以使用any_instance_of,但显然这是一种气味?

1 个答案:

答案 0 :(得分:1)

如果您想测试inside方法的行为,可以在Location设置期望以返回您的实例,如:

expect(Location).to receive(:find).with(location.id).and_return(location)