Dennis Nedry
Dennis Nedry

Reputation: 4777

Ruby Minitest: Access variables in setup-method

How can I access variables that are defined inside the setup method in Minitest?

require 'test_helper'

class TimestampTest < ActiveSupport::TestCase
  setup do
    @ag = AG.create(..., foo = bar(:foobar))
    @ap = AP.create(..., foo = bar(:foobar))
    @c  = C.create(..., foo = bar(:foobar))
  end

  [@ag, @ap, @c].each do |obj|
    test "test if #{obj.class} has a timestamp" do
      assert_instance_of(ActiveSupport::TimeWithZone, obj.created_at)
    end
  end
end

If I run this @ag, @ap and @c are all nil. bar(:foobar) on line 5-7 is needed to access fixture-data.

Upvotes: 3

Views: 1937

Answers (1)

tadman
tadman

Reputation: 211740

You're creating instance variables, and then later expecting them to exist in the class context. There's also an order of operations problem that you're missing: The setup method is run only after the class is fully defined, yet you're immediately exercising those variables to define the class.

If you need those to execute immediately, remove the setup do ... end block. It's also better to follow Ruby conventions and define it like this:

class TimestampTest < ActiveSupport::TestCase
  CLASSES = [
    AG,
    AP,
    C
  ]

  setup do
    @time_zones = CLASSES.map do |_class|
      [
        class.name.downcase.to_sym,
        _class.create(...)
      ]
    end.to_h
  end

  test "test if things have a timestamp" do
    @time_zones.each do |type, value|
      assert_instance_of(ActiveSupport::TimeWithZone, value.created_at)
    end
  end
end

As a note, your pseudo-code with a method call of the form (..., foo=...) creates an extraneous variable foo for no reason. That should be omitted unless you meant foo: ... where that's a named keyword argument.

Upvotes: 4

Related Questions