开发者

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:

  1. Remove all non-core plugins
  2. Check that the core tests pass
  3. Install PluginA
  4. cd into PluginA's directory
  5. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜