Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I run a Rails engine's specs from a real app which mounts it?

I have a Rails Engine meant to provide some models and controllers to a larger project of ours. There's a pretty decent set of specs for the Engine, using a bunch of mocks and some full-scale models and controllers within the engine's dummy app to make sure the Engine is doing what it's supposed to and working with the larger application.

However, even with all tests passing, I frequently find broken behavior when I update the engine in the larger application. If my tests are passing but the behavior is broken, clearly something's wrong with the tests, but what? Am I mocking too much, or not enough?

To get me closer to figuring this out, I'd like to be able to run the engine's tests from inside the full application. This seems like it should be possible, but I don't understand rspec thoroughly enough to get a handle on how.

(This is related to this question but not quite the same; I'm not trying to run all the specs from one command, just to run the engine's specs within the full app environment. This also seems to be related. Actually, I've read every question tagged with both rspec and rails-engines--there aren't many--and they're all either not what I need, or unanswered.)

like image 388
pjmorse Avatar asked Sep 19 '12 16:09

pjmorse


1 Answers

The simplest solution would be to specify the paths in rspec command. If you have directory structure

/project
/engine
/engine_2

Then you do and should run all the specs

cd project
rspec spec/ ../engine/spec ../engine_2/spec

But if you want to run specs on Continous Integration or just this doesn't seem to be comfortable I solved this problem with a customized rake spec task, changing the pattern method.

lib/task/rspec.rake should look like this

require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)

task :default => :spec
RSpec::Core::RakeTask.module_eval do
  def pattern
    extras = []
    Rails.application.config.rspec_paths.each do |dir|
      if File.directory?( dir )
        extras << File.join( dir, 'spec', '**', '*_spec.rb' ).to_s
      end
    end
    [@pattern] | extras
  end
end

In engine class you add a path to config.rspec_paths

class Engine < ::Rails::Engine
  # Register path to rspec
  config.rspec_paths << self.root
end

And don't forget to initialize config.rspec_paths somewhere in a base project.

If you want to add factories then you can create initializer, you can find solution somewhere here on stackoverflow.

Not sure if this solution is the best but works for me and I am happy with that. Good luck!

like image 72
Kamil Jopek Avatar answered Oct 20 '22 08:10

Kamil Jopek