rpeczykowski
rpeczykowski

Reputation: 165

Rspec test readonly model

I have small aplication in rails 5. I tried to use Rspec to test it but failed with readonly model.

I have readonly model Product and normal model ProductMsp. The second one a is list of all prices associated to Product and is stored in Rails DB. Product is a external readonly connection with another database to withdraw list of products.

I added association to product to spec/factories/product_msps.rb.

FactoryGirl.define do
  factory :product_msp do
    product_id 11
    initial_date '01-01-2017'
    expiry_date '31-01-2017'
    msp 9999.99
    association :product
  end
end

I didn't add any new test. When I run rspec once again I get failures. Probably rspec want to create products, but cannot due to readonly database table.

Failures:
    1) ProductMsp Validations initial_date cannot by empty
    Failure/Error: pm = FactoryGirl.build(:product_msp, initial_date: nil)    
        ActiveRecord::ReadOnlyRecord:
            Product is marked as readonly
                 # ./spec/models/product_msp_spec.rb:17:in `block (3 levels) in <top (required)>'

Below is failing test: (there is more failures)

require 'rails_helper'

RSpec.describe ProductMsp, type: :model do
    it 'initial_date cannot by empty' do
      pm = FactoryGirl.build(:product_msp, initial_date: nil)
      pm.valid?
      expect(pm.errors[:initial_date]).to include("can't be blank")
    end
end

spec/factories/products.rb

FactoryGirl.define do
  factory :product do
    id 11
    name 'Porsche Cayenne'
  end
end

and app/model/product.rb

class Product < ApplicationRecord
  self.primary_key = 'tw_Id'

  def readonly?
    true
  end

  has_many :product_msps

  default_scope {where(product_type:1).order(:name)}

A the main question is: How to deal with test and readonly models?

I searched through internet but I didn't find any examples of such problem. I need to build app on top of another database, but I would like to have it tested somehow. :-)

Upvotes: 3

Views: 2600

Answers (2)

aaronkelton
aaronkelton

Reputation: 409

You should disable persistence using skip_create, per the FactoryGirl (now FactoryBot) documentation:

factory :product do
  skip_create
end

You can also run FactoryGirl.lint according to the linting documentation. If one of your factories returns:

* product - Product is marked as readonly (ActiveRecord::ReadOnlyRecord)

then you know you should use the skip_create feature.

Upvotes: 4

Ngoral
Ngoral

Reputation: 4824

(For future searchers:) )

You should add skip_create to your factory for the read-only model. That allows avoiding database record creation and should solve the problem for this. It is also useful if you want to create a factory for a class, that is not connected to the database (does not inherited from `ActiveRecord::Base).

Upvotes: 5

Related Questions