Search code examples
ruby-on-railsrubyactiverecordrspecrspec-rails

Stubing record creation in Rspec


I've a builder class which is supposed to creating new record, let's say:

ObjectBuilder creates Object

Object it's a ActiveRecord::Base inherited class.

I'd like to test in Rspec if specific record is created.

But It's good enough to test only if specific record will be created, without database call. So How I can stub AR object to check this ?

Responding to potential answers I'm not able to integrate NullDB to my project and I won't to create custom method in Object which will be responsible for creating record, and would be easy to stub. I would like to rely on ActiveRecord interface.


Solution

  • I think you need to decide exactly what you're trying to test here. If you're testing whether ActiveRecord works then you're going down the wrong path. ActiveRecord is itself thoroughly tested and any further tests you add yourself within your application are somewhat redundant.

    Have a look here for the ActiveRecord tests, how they work, what they cover, etc: https://github.com/rails/rails/tree/master/activerecord/test

    What I think you probably mean to test is whether your object is capable of being saved when you call @object.save in your application. If this is the case, then you can easily test this without really saving the object simply by calling the #valid? method. If an object is not valid, ActiveRecord will not save it.

    Something like this would suffice:

    require 'spec_helper'
    
    describe Object do
      before(:each) do
        object = Object.new(attr1: 'required')
      end
    
      it "is valid with required attributes" do        
        expect(object).to be_valid
      end
    
      it "is not valid without an attr1" do
        object.attr1 = nil
        expect(object).not_to be_valid
      end
    end
    

    You can more comprehensively test the validations by adding the rspec-collection_matchers gem to your project and doing something like this:

    it "is not valid without an attr1" do
      object.attr1 = nil
      expect(object).to have(1).errors_on(:attr1)
    end