Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for fixtures #163

Open
spicybackend opened this issue Mar 21, 2018 · 4 comments
Open

Support for fixtures #163

spicybackend opened this issue Mar 21, 2018 · 4 comments

Comments

@spicybackend
Copy link
Contributor

It would be great to have fixture support (similar to Rails' ActiveRecord::Fixtures) that allows for clean spec setup and scenarios.

@robacarp
Copy link
Member

robacarp commented Mar 21, 2018

@yumoose thanks for the suggestion.

Until Granite/Amber gets a solution to this, I'd like to propose a solution to this problem which is reasonably easy to configure and extend, and doesn't obfuscate quite like fixtures do.

Create a class called Generate which contains a few class methods which can be used as helpers to quickly generate model instances:

class Generate
  def self.address
    Address.new.tap do |a|
      a.first_name = "Elwin"
      a.last_name = "Ransom"
      a.street_1 = "1 Malacandra Street"
      a.street_2 = "Hyoi's Water Dwelling n1"
      a.city = "Malacandra"

      a.country = Country.usa
      a.province = a.country.provinces.sample
      a.postal_code = '80019'
    end
  end
end

Require this in your test helper file, and then in a test you can do stuff like this:

# create an address with default test data
address = Generate.address

# insert an address into the database
Generate.address.save

# override attributes for an instance
address = Generate.address.tap do |a|
  a.country = "The Shire"
end

# create a helper method which overrides attributes and persists the object
def frodos_address
  Generate.address.tap do |a|
    a.country = "The Shire"
    a.first_name = "Frodo"
    a.last_name = "Baggins"
  end
end

# and use that in a spec
describe "addresses" do
  context "with a country" do
    it "does stuff" do
      frodos_address.should be_an Address
    end
  end
end

This is an application of a pattern I've used in Ruby projects many times and documented as a gist. I'm sure that a few of the metaprogrammy concepts won't translate directly to crystal, but with a little tinkering it wouldn't be hard to come up with a reasonable library.

@Blacksmoke16
Copy link
Contributor

Blacksmoke16 commented Jul 17, 2018

Once #253 gets merged it could be doable with JSON files. Read JSON/array of JSON from file and instantiate a model with given JSON values.

EDIT: Could also use YAML after #255 ;)

@Blacksmoke16
Copy link
Contributor

We should have a discussion on how this should work before we/I get too far into the weeds. Currently I have a simple YAML version working, similar to AR.

However, @robacarp had a different approach, similar to his example earlier. @yumoose @drujensen Think we can reach a good pattern on how to set this up?

@spicybackend
Copy link
Contributor Author

I like @robacarp's generator approach, though this also requires supporting code for each model which can be a bit more of a hassle than static fixture sets for simple models that don't need too much configuration for their use in tests.

I'd personally love something similar to ActiveRecord using YAML files, but that's just what I'm used to. Both choices or a mix would be great for different situations as required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants