I get intermittent test failures when using instance_double.
I have a file with 4 specifications. Here is the source:
require 'rails_helper' describe SubmitPost do before(:each) do @post = instance_double('Post') allow(@post).to receive(:submitted_at=) end context 'on success' do before(:each) do allow(@post).to receive(:save).and_return(true) @result = SubmitPost.call(post: @post) end it 'should set the submitted_at date' do expect(@post).to have_received(:submitted_at=) end it 'should call save' do expect(@post).to have_received(:save) end it 'should return success' do expect(@result.success?).to eq(true) expect(@result.failure?).to eq(false) end end context 'on failure' do before(:each) do allow(@post).to receive(:save).and_return(false) @result = SubmitPost.call(post: @post) end it 'should return failure' do expect(@result.success?).to eq(false) expect(@result.failure?).to eq(true) end end end
This is a Rails 4.1.4 application. Internally, SubmitPost sets submit_at and causes it to be saved on sent mail. My Post model is as follows:
class Post < ActiveRecord::Base validates :title, presence: true validates :summary, presence: true validates :url, presence: true validates :submitted_at, presence: true scope :chronological, -> { order('submitted_at desc') } end
This is super vanilla.
When I run rake , rspec or bin/rspec , I get all four tests with an error of 20% - 30% of the time. The error message is always:
Failure/Error: allow(@post).to receive(:submitted_at=) Post does not implement: submitted_at=
If I tag one of the specs with focus: true , then one spec will fail 100% of the time.
If I replaced instance_double with double , all specifications will succeed for 100% of the time.
It seems that instance_double is having a hard time outputting the methods available in the Post class. It also seems somewhat random and time-based.
Has anyone encountered this problem? Any ideas what might be wrong? Any feeling how to solve the problem? Naturally, inserting a debug breakpoint causes specifications to skip 100% of the time.