Run examples when using another DB connection

62 views
Skip to first unread message

Javix

unread,
Jun 27, 2018, 4:53:03 AM6/27/18
to rspec
I need to execute some rake tasks agains a database other than defined in database.yml, test group. Here is how database.yml looks like:

default: &default
  adapter
: postgresql
  encoding
: unicode
  user
: postgres
  password
:
  pool
: 5


development
:
 
<<: *default
  database
: decastore_development
  host
: <%= ENV['DECASTORE_DATABASE_HOST'] %>


test
:
 
<<: *default
  database
: decastore_test
  host
: <%= ENV['DECASTORE_DATABASE_HOST'] %>


production
:
 
<<: *default
  host
: <%= ENV['DECASTORE_DATABASE_HOST'] %>
  database
: XXXX
  username
: XXXXX
  password
: <%= ENV['DECASTORE_DATABASE_PASSWORD'] %>


mystore
:
  adapter
: oracle_enhanced
  host
: <%= ENV['mystore_db_host']%>
  port
: <%= ENV['mystore_db_port']%>
  database
: <%= ENV['mystore_db_name']%>
  username
: <%= ENV['mystore_db_user']%>
  password
: <%= ENV['mystore_db_password']%>


Is it possible to mix 2 database settings when running tests or I have to mock it everywhere ?
Thank you.

Jon Rowe

unread,
Jun 27, 2018, 8:16:22 AM6/27/18
to rs...@googlegroups.com
Hi Javix

RSpec itself has no database integration so it's certainly possible, you'll need to either configure a connection manually to talk through or use however you'd normally talk to your other database.

If you’re using rspec-rails you’ll need to figure out how Rails does it’s transactional testing for multiple databases, but most 3rd party gems support “cleaning” multiple databases, including DatabaseCleaner.

HTH
Jon

--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/f723fd63-26b2-4ff7-a9ff-b8a3a69567f3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

belgoros

unread,
Jun 27, 2018, 9:06:51 AM6/27/18
to rspec
I had to modify my base class by adding
unless Rails.env.test?

condition:


module MystoreMigration
 
class MystoreModel < ActiveRecord::Base
   
self.abstract_class = true
    establish_connection
(:mystore) unless Rails.env.test?
 
end
end


All other model classes used by rake tasks inherit from the above model. In this case I'll have to mock all the DB calls related to this rake task to avoid it to establish mystore  connection defined in `database.yml` and used by all the tasks models.

Jon Rowe

unread,
Jun 27, 2018, 9:43:33 AM6/27/18
to rs...@googlegroups.com
Sorry I misunderstood your question!

What you need to do is specify multiple environments for your second database, so you can establish an environment specific connection. As you can see from your own configuration thats the standard pattern, so you could then use `establish_connection` with the appropriate db e.g. `establish_connection(:”mystore_#{Rails.env}”)` and have a test version of your second DB

Cheers
Jon Rowe
---------------------------

Serguei Cambour

unread,
Jun 27, 2018, 9:49:10 AM6/27/18
to rs...@googlegroups.com
Thank you John !
What I need is to migrate some data from one DB (mystore connection) to another. That's why I had to write some specific Rake tasks to match tables attributes to be imported (mystore connection) to another DB defined in development group in database.yml. Sure, I'd like to write some tests and I had an impression that when accessing a class that used mystore connection, RSpec tried to use the default connection defined in test group of database.yml. Is the way I'm truing to do that in testing correct ? Thank you.

You received this message because you are subscribed to a topic in the Google Groups "rspec" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rspec/sbRqzLR_Lug/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rspec+un...@googlegroups.com.

To post to this group, send email to rs...@googlegroups.com.

Jon Rowe

unread,
Jun 27, 2018, 10:26:36 AM6/27/18
to rs...@googlegroups.com
> Sure, I'd like to write some tests and I had an impression that when accessing a class that used mystore connection, RSpec tried to use the default connection defined in test group of database.yml. Is the way I'm truing to do that in testing correct ?

No, RSpec doesn’t do *any* database configuration, Rails will use the environment named configuration by default, but `establish_connection` *should* override it.

If it’s not behaving as you expect you might want to check that Rails is loading your files correctly (as until `establish_connection` is called you won’t have configured the other database).

Cheers

Jon Rowe
---------------------------

s.cambour

unread,
Jun 27, 2018, 10:32:04 AM6/27/18
to rspec
Yep, this is exactly the behaviour I wanted - to establish a
connection different to a conventional one ONLY in classes used by
the above rake task. That's why I declared establish_connection in the
base class inherited by all the other model classes called by the
task. Thank you for your time.

belgoros

unread,
Jun 27, 2018, 11:04:35 AM6/27/18
to rspec


On Wednesday, 27 June 2018 16:26:36 UTC+2, Jon Rowe wrote:
> Sure, I'd like to write some tests and I had an impression that when accessing a class that used mystore connection, RSpec tried to use the default connection defined in test group of database.yml. Is the way I'm truing to do that in testing correct ?

No, RSpec doesn’t do *any* database configuration, Rails will use the environment named configuration by default, but `establish_connection` *should* override it.

If it’s not behaving as you expect you might want to check that Rails is loading your files correctly (as until `establish_connection` is called you won’t have configured the other database).

Finally, it does not work as expected when using 

establish_connection(:mystore) unless Rails.env.test?

If I use just

establish_connection(:mystore)

I have another error when calling new on one of the mystore DB models:

ORA-12162: TNS:net service name is incorrectly specified

Does RSpec tries to access mystore_test table ?

belgoros

unread,
Jun 27, 2018, 11:06:24 AM6/27/18
to rspec


On Wednesday, 27 June 2018 17:04:35 UTC+2, belgoros wrote:


On Wednesday, 27 June 2018 16:26:36 UTC+2, Jon Rowe wrote:
> Sure, I'd like to write some tests and I had an impression that when accessing a class that used mystore connection, RSpec tried to use the default connection defined in test group of database.yml. Is the way I'm truing to do that in testing correct ?

No, RSpec doesn’t do *any* database configuration, Rails will use the environment named configuration by default, but `establish_connection` *should* override it.

If it’s not behaving as you expect you might want to check that Rails is loading your files correctly (as until `establish_connection` is called you won’t have configured the other database).

Finally, it does not work as expected when using 

establish_connection(:mystore) unless Rails.env.test?

If I use just

establish_connection(:mystore)

I have another error when calling new on one of the mystore DB models:

ORA-12162: TNS:net service name is incorrectly specified

Does RSpec tries to access mystore_test table ?
 
Sorry, I meant mystore_test database. Thank you.

Jon Rowe

unread,
Jun 28, 2018, 3:37:33 AM6/28/18
to rs...@googlegroups.com
Sorry, no it doesn’t, RSpec doesn’t do *any* database connection work.

Your code is trying to access the database :mystore from your `config/database.yml` as thats what you’ve told it to do, perhaps your environment variables are empty on your local machine?

Jon Rowe
---------------------------

Serguei Cambour

unread,
Jun 28, 2018, 7:52:32 AM6/28/18
to rs...@googlegroups.com
I have the following environment variables for mystore environment in database.yml:

mystore:
  adapter: oracle_enhanced
  host: <%= ENV['mystore_db_host']%>
  port: <%= ENV['mystore_db_port']%>
  database: <%= ENV['mystore_db_name']%>
  username: <%= ENV['mystore_db_user']%>
  password: <%= ENV['mystore_db_password']%>

defined in 'development' section in application.yml (I'm using Figaro gem):

development:
  mystore_db_port: "XXXX"
  mystore_db_name: "XXXX"
  mystore_db_user: "XXXX"
  mystore_db_password: "XXXX"

test:
  client_id: "XXX"
  client_secret: "XXX
....

Should I add them to test section as well ?

Jon Rowe

unread,
Jun 28, 2018, 7:57:18 AM6/28/18
to rs...@googlegroups.com
Without knowing the specifics of the figaro gem I would wager yes, as they would appear to be blank.

Jon Rowe
---------------------------

belgoros

unread,
Jun 29, 2018, 5:05:16 AM6/29/18
to rspec


On Thursday, 28 June 2018 13:57:18 UTC+2, Jon Rowe wrote:
Without knowing the specifics of the figaro gem I would wager yes, as they would appear to be blank.

OK, figaro gem makes it possible to separate the variables by environment in its appication.yml file.
If I add mystore connection variables to test environment in application.yml, - IT WORKS.
What is weird is that why RSpec is trying to check the connection to mystore  and ignores the below check in my base model class:

module MystoreMigration
 
class MystoreModel < ApplicationRecord

    establish_connection
(:mystore) unless Rails.env.test?
 
end
end

A simple test fails even if I use double to mock a mystore related model:

require 'rails_helper'


RSpec.describe MystoreMigration::StoreMigrator do

  let
(:shop) { build(:shop) }
  let
(:store) { double(MystoreMigration::StoreInfo)}
  let
(:store_migrator) { MystoreMigration::StoreMigrator.new([store]) }

  describe
'initialization' do
    it
'should have stores initialized' do
      expect
(store_migrator.stores).not_to be_empty
   
end
 
end

Here is the class under test:

require_relative 'store_schedule_period'
require_relative
'store_welcome'


module MystoreMigration
 
class StoreMigrator

    MIGRATOR
= 'mystore.store.migrator'.freeze
    DEFAULT_SHOP_CATEGORY
= 'decathlon'.freeze

    attr_reader
:stores

   
def initialize(stores = [])
     
@stores = stores
   
end

...

Is it Rails loading stuff or smth else ?
Sure, I would not like to connect to mystore database in test mode and do whatever operations. That's why I'll have to mock all the methods calls to it.
Any idea ? Thank you.

Jon Rowe

unread,
Jun 29, 2018, 6:03:39 AM6/29/18
to rs...@googlegroups.com
You need to give your test mode a safe DB to talk to, Rails will not like not having a connection.

Again this has nothing to do with RSpec, RSpec is not configuring anything it is all Rails.

You will need to have `RAILS_ENV=“test”` somewhere before Rails is loaded in order for your bypass to work, and if theres another `establish_connection` somewhere it will override it.

Also if you are using spring you will need to restart it when modifying this check.

Jon Rowe
---------------------------

Serguei Cambour

unread,
Jun 29, 2018, 8:09:43 AM6/29/18
to rs...@googlegroups.com
So it is Rails....
Yes, I have RAILS_ENV set up to test in rails_helper.rb

require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'

This file is copied to spec/ when you run 'rails generate rspec:install'.

Reply all
Reply to author
Forward
0 new messages