How do I get cucumber and pickle working with mong

2019-07-12 16:36发布

问题:

I would like to get machinist, machinist_mongo, mongo_mapper, cucumber and pickle to play nice together.

Currently I have machinist with all my blueprints configured and am using cucumber to do BDD. So far so good. My problem is I am having to write custom cucumber steps for all of my machinist blueprints. It is not really a problem per se, since it is not stopping me in my tracks, but as a .NET dev checking out rails, it feels really dirty to have to write a step for each blueprint whereas in .NET I could probably use reflection.

Is there any way I can get pickle's built in capture_model, capture_plural_factory, etc, to recognize my machinist blueprints?

I am pretty confident I have machinist configured and set up correctly, because when I use blueprintname.make, in a custom cucumber step, everything works out correctly.

Gem versions:
rails 2.3.8
cucumber 0.8.3
cucumber-rails 0.3.2
mongo 1.0.5
mongo_mapper 0.8.2
pickle 0.3.0
machinist 1.0.6
machinist_mongo 1.1.1


features/support/pickle.rb:
require 'pickle/world'
Pickle.configure do |config|
  config.adapters = [:machinist]
end

I tried using config.adapters = [:machinist, Machinist::MongoMapperAdapter] but I get an error stating that there is no method factories for Machinist::MongoMapperAdapter.

undefined method `factories' for Machinist::MongoMapperAdapter:Class (NoMethodError) /usr/local/lib/ruby/gems/1.8/gems/pickle-0.3.0/lib/pickle/config.rb:25:in `factories'

features/support/machinist.rb:
require 'machinist'
require 'machinist/mongo_mapper'
require "#{Rails.root}/spec/blueprints"
require 'database_cleaner'
Before { Sham.reset } # reset Shams in between scenarios
spec/blueprints.rb (truncated for clarity)
require 'sham'
require 'faker'

Sham.code { Faker::Lorem.words 1 }

AccessCode.blueprint do
  code
end
app/models/access_code.rb
class AccessCode
  include MongoMapper::Document

  key :code, String, :required => true
end

回答1:

After days of beating my head against the wall, I have everything mostly working (I say mostly working because I'm not sure if there is something wrong that I haven't discovered yet). The fix was actually pretty simple once I figured it out.

To resolve the issue, and get my cucumber steps working with pickle, I changed MongoMapper::Document to include Pickle::Adapter::Base. I used lib/pickle/adapters/active_record.rb and data_mapper.rb (same path as active_record.rb) that come with pickle as an example. I did still need machinist_mongo, presumably to hook up pickle to my machinist blueprints.

I can't take credit for the code in def self.model_classes - it is stolen from tjtuom's pickle fork.

PS. If this is the completely wrong way to do it, please feel free to criticize or give suggestions, I am a complete ruby noob.

module MongoMapper::Document
  module PickleAdapter
    include Pickle::Adapter::Base

    def self.model_classes
      @@model_classes ||= ::MongoMapper::Document.descendants.to_a +
        ::MongoMapper::Document.descendants.map { |klass| klass.subclasses }.flatten
    end

    # get a list of column names for a given class
    def self.column_names(klass)
      klass.column_names
    end

    # Get an instance by id of the model
    def self.get_model(klass, id)
      klass.find(id)
    end

    # Find the first instance matching conditions
    def self.find_first_model(klass, conditions)
      klass.find(:first, :conditions => conditions)
    end

    # Find all models matching conditions
    def self.find_all_models(klass, conditions)
      klass.find(:all, :conditions => conditions)
    end
  end
end

Set up pickle for machinist:

Pickle.configure do |config|
  config.adapters = [:machinist]
end

To configure database_cleaner for mongo:

require 'database_cleaner'
require 'database_cleaner/cucumber'

DatabaseCleaner.orm = 'mongo_mapper'
DatabaseCleaner.strategy = :truncation