How to get other Gem helpers into my Engine Gem's tests? - ruby-on-rails

I'm trying to write tests for an engine gem I'm writing. I'm using Rspec and the tests seem to be running fine. But whenever a view uses a helper from another gem, such as "will_paginate" or "ransack", I get an "undefined method" error.
I've tried including the other gems in my gem's Gemfile (in addition to the engine.gemspec file) as well as the dummy app's Gemfile, but I get the same error. I've also tried including the gems in the spec/spec_helper.rb file.
So I've tried most of the things mentioned here:
Setup RSpec to test a gem (not Rails)
Usually, for Rspec tests for a regular Rails app, these helpers seem to be just included some how since I don't have this issue running tests for a regular Rails app.
I also have been needing to namespace my url helpers in the views with something like:
engine.resources_path
I'm not sure if that's a symptom of some configuration I've messed up on.
Everything in the engine runs fine when mounted to another app and viewed on the browser.
Any ideas?

Turns out a better approach is to stub out methods from gems since the gem should be testing their own methods anyways. Please let me know if I'm misunderstanding anything. Thanks!

Related

Loading Rails project's app paths in Rspec

I'm writing an application in Rails 5 and using Rspec for tests. I'm having a lot of trouble with require 'some_model' or require 'some_controller' in my spec files. Every time I run a spec, it acts lost and doesn't seem to understand that it's in a Rails app. The suggestions I've seen range from
config.autolad_paths += %W( #{config.root}/app )
to
$LOAD_PATH << '~/my_app/app/models' which sort of works, except that my tests throw an unitialized constant for ApplicationRecord
So for all the digging around I've done, I still haven't found a good way require my MVC files while keeping my specs and spec_helper clean. There doesn't seem to be any defacto way to do so, so how do you all suggest doing it?
can you not take on the entire stress of RSpec configuration. Use the rspec-rails gem and look through the documentation to use it within your app. I guess you can get a base config with rails generate rspec:install after including the gem in your project.

Rails Engines: Where to define gems only used in testing

I'm building an engine, and I want to use VCR and Webmock for testing.
The documentation within the Gemfile generated when an engine is created, seems to suggest that all an engine's gems should be loaded via gemspec, but the only options for this are add_dependency and add_development_dependency. If I use the latter, VCR and Webmock get loaded into my development environment, and I then have to explicitly disable Webmock in the development environment. I'd rather not do that as a host app may want these gems to work in development, and my engine disabling them may be unexpected.
The obvious solution would appear to be to use the engine's Gemfile:
group :test do
gem 'vcr'
gem 'webmock'
end
Is this the right way to load gems that are only used when testing an engine?
Are there any gotchas doing this?
One of the well known rails engines, rails_admin (https://github.com/sferik/rails_admin) uses that approach, so I believe it can be considered a good practice.
What's the load order for Rails app and Rails app's Rails Engines?
My guess is that the Rails app Gemfile is the determining factor for a gem being loaded or not loaded. This might be worth a try in a Rails test app.
I believe the answer is that there is nothing wrong with declaring in an engine's Gemfile, gems only used for testing and debugging the engine code. Further, I think the Gemfile template should be made less ambiguous, and have submitted a pull request to this effect:
https://github.com/rails/rails/pull/11881

How to correctly embed a test Rails application inside the gem that it tests?

I have a small gem that I have created and a separate small Rails application that I use to test the gem.
I have been looking for information about how I could embed the test rails app inside the gem so it's packaged as one and so I can launch it to test the application.
I have currently got it inside the gem tree in a subdirectory of test. I can change to that subdirectory and run the app up ok, or I can run its tests with rake. But is this the correct way to do this ?
(in case it makes any difference, this gem and the small test app are for Rails 2.x)
I'd suggest you take a look at some other gems on github and what they do. Some probably don't need a full rails app, but devise, for instance has a barebones rails app embedded at /test/rails_app
https://github.com/plataformatec/devise/tree/master/test/rails_app

RSpec/Gem development: Stubbing rails templates

I'm currently working on a couple of different gems both of which mainly consist of rails view helpers.
My problem is that some of these helpers require rendered rails templates to test the output - but I am unsure of the best way to stub a template, without a rails application. I presume that I should be able to leverage rspec-rails in some capacity, but i've been having trouble getting that to work without a rails app present.
Am I approaching this the wrong way? What's the current best-practice to test rails-specific features (in particular - things that happen only in the view) during gem development?
I use the excellent enginex gem, which helps you in setting up a gem skeleton with an embedded rails application for testing. This way you can easily test any rails dependency inside that application. To generate rspec tests run it as follows (default is test-unit):
enginex -t rspec your-gem-name
What I did to incorporate this into my gem, was run this inside some test folder, and copied the necessary files over to my gem. As an example, you could check it out inside my cocoon gem.
Hope this helps.

Proper way of testing gems

If a gem has rails dependencies, do you think it is better to write the gem tests in a way they can be run standalone or run them under a rails project?
A gem should be a piece of code which acts stand-alone. Otherwise it is part of the application, so the tests should be created stand-alone as well. In this way others (hypothetically) can perform the tests as well. If the tests depend on your application others cannot test your gem.
Furthermore when you want to test your gem it should not fail because your application is failing. After your gem passed the test, you can test the application knowing that your gem is functioning well (assuming that you tested everything).
Whether the gem is depending on Rails or not is not an issue, since Rails also has been tested (and you can assume it is working properly). So these dependencies do not (/should) influence your gem.
I'd say it depends on the kind of dependencies the gem needs. Eg. if it's just the ActiveRecord it's quite easy to include it into your test suite. In more complex cases you can always mock some of the needed functionality. In a really complex cases, creating a test app is better than nothing (IMO).

Resources