martins
martins

Reputation: 10009

Variables created in initialiser not available in test, but from console(Ruby on Rails)

I've created a library I want to initialize once when the app starts. So I've written an initializer that does this. And this seam to work when I start rails console, but @push_notifications is not available from my tests. How can that be?

app/models/post.rb

class Post < ApplicationRecord
  after_save :send_notifications

spec/models/post_spec.rb

require "rails_helper"

RSpec.describe Post, type: :model do
  before(:each) do
    @user = Fabricate(:user)
    @post = Fabricate(:post, user: @user)
  end

  it "is valid from the fabric" do
    expect(@post).to be_valid
  end

lib/push_notifications.rb

class PushNotifications
  def initialize
    puts "PushNotifications#initialize"
    FCM.new(ENV["FCM_SERVER_KEY"])
  end

  def new_post_in_group(post:)
    # [cut...]
  end

config/initializers/PushNotifications.rb

require "#{Rails.root}/lib/push_notifications"

puts "initialize PushNotifications"
@push_notifications ||= PushNotifications.new

$ rails console

initialize PushNotifications
PushNotifications#initialize


[1] pry(main)> @push_notifications
=> #<PushNotifications:0x00007fa22650b250>

running tests

rspec spec/models/post_spec.rb
initialize PushNotifications
PushNotifications#initialize

Post
  is valid from the fabric (FAILED - 1)

Failures:

  1) Post is valid from the fabric
     Failure/Error: @push_notifications.new_post_in_group(post: self)

     NoMethodError:
       undefined method `new_post_in_group' for nil:NilClass
     # ./app/models/post.rb:85:in `send_notifications'

Upvotes: 1

Views: 94

Answers (2)

mdesantis
mdesantis

Reputation: 8507

@push_notifications is an instance variable, so it's instance context-dependent, you should assign it to a constant:

PUSH_NOTIFICATIONS = PushNotifications.new

Upvotes: 2

Jay Schneider
Jay Schneider

Reputation: 325

Your Question is incomplete, please include a codesnippet of the spec that fails (the output of rspec is not very helpful here).

In Pry you are often "inside" objects, meaning you can access data which is not visible from the outside. For access from outside you might need an attr_reader :push_notifications in the respective class.

Setting instance variables in the initializer is probably not what you want. Where should your @push_notifications object be available from? Is it something that you need in your controllers? Then you should initialize - and store - it there (in a specific controller or if needed everywhere in an ApplicationController < ActiveRecord::Base class from which every other controller inherits. Is it something you need in a special model (like in Post) then define it over there.

Also is it correct that your PushNotification class creates a FCM object but does not store a reference to it? What is FCM supposed to do?

Upvotes: 0

Related Questions