Is there a way to monkey-patch rails tests from plugins?
Me and my team have been heavily producing plugins for a Rails 2.3 app (Redmine, currently 1.1 branch). So far, we have contained from polluting Redmine's base code by writing most of our changes as rails plugins. This has two main benefits:
- Most of the time, integration with newer Redmine versions is straightforward.
- We can enable/disable some custom behavior by dropping/removing a plugin. In fact, this is a key factor for us, because our clients have quite disparate requirements.
Some of our plugins monkey-patch Redmine's classes. For instance, we have a plugin that "injects" stricter validations to the Issue
model: start_date
, due_date
and estimated_hours
are required for leaf?
issues.
This monkey-patching stuff makes several tests fail and/or raise exceptions. This very plugin, for instance, makes the create_issue!
method from IssueNestedSetTest
class to create invalid issues (i.e. lacking the required attributes the plugin is enforcing):
# Helper that creates an issue with default attributes
def create_issue!(attributes={})
Issue.create!({:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test'}.merge(attributes))
end
Since the plugin may or may not be active, we would not like to change the test itself. We think it's best the plugin monkey-patch the test accordingly:
module StandardTestPatches
module InstanceMethods
def create_issue_with_gespro_standards!(attributes={})
attribu开发者_高级运维tes.merge!(:start_date => 1.day.ago, :due_date => 1.day.from_now, :estimated_hours => 8)
create_issue_without_gespro_standards!(attributes)
end
end
def self.included(base)
base.send :include, InstanceMethods
base.class_eval do
alias_method_chain :create_issue!, :gespro_standards
end
end
end
However since our plugin's init.rb
file is required before the tests classes are loaded we can't monkey-patch the IssueNestedSetTest
class there.
Is there a way to monkey-patch rails tests from plugins?
UPDATE: Still an open question. Making it available at http://www.redmine.org/boards/1/topics/23672
Whenever I write Redmine or ChiliProject plugins I always assume that:
- the plugins' tests will run on their own (inside of the plugin dir)
- the plugin might modify the core code enough that the core tests will fail
I've tried to help others work around this by patching the core tests but we never found a good solution. Either the test would change in the core, another plugin would break something, or something else. I even tried to mock out the interfaces in the tests but maintaining them were a time killer.
What I recommend (and do) is:
- Remove all non-core plugins
- Check that the core tests pass
- Install PluginA
- cd into PluginA's directory
- Run PluginA's tests in isolation
(And you might run into problems later on if PluginA and PluginB are both installed)
Sorry there isn't a better solution.
精彩评论