1
\$\begingroup\$

I know there is a balance to be struck between writing dry code and damp code but I have the feeling that this is a bit too repeative. Is there a terse yet self explainatory way to rewrite these tests?

class TripTest < ActiveSupport::TestCase
  def setup
    @trip = trips(:one)
    @invoice = invoices(:one)
  end

  test 'trip can save' do
    trip = Trip.new
    trip.departure_date = "2040-03-24"
    trip.depart_airport = "DHW"
    trip.arrive_airport = "ABC"
    trip.invoice_id = 123534

    assert trip.save, "Error message: #{trip.errors.full_messages}"
  end

  test "one invoice can have multiple trips" do
    trip = Trip.new
    trip.departure_date = "2040-03-24"
    trip.depart_airport = "DHW"
    trip.arrive_airport = "ABC"
    trip.invoice_id = 123534
    @invoice.trips.push(trip)
    @invoice.save

    trip = Trip.new
    trip.departure_date = "2040-03-24"
    trip.depart_airport = "ICN"
    trip.arrive_airport = "XYZ"
    trip.invoice_id = 123534
    @invoice.trips.push(trip)
    @invoice.save

    assert @invoice.trips.size > 1
  end
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

If you're writing verbose tests, your test suite will skyrocket in length.

There are worse problems to have but your best asset to address this problem is a comprehensive test_helper class.

It doesn't matter what you call the file. Just load it up into your main test file with a require_relative.

In your example, it's fairly obvious which code is being repeated between methods. So you could refactor your code as follows:

# in test_helpers.rb
module TestHelpers
  def initialize_sample_trip(options={})
    Trip.new(
      departure_date: options[:departure_date]   || "2040-03-24"
      default_airport: options[:default_airport] || "DHW"
      arrive_airport: options[:arrive_airport]   || "ABC"
      invoice_id: options[:invoice_id]           || 123534
    )
  end
end

...

# in your main test file
require_relative './test_helpers.rb'
class TripTest < ActiveSupport::TestCase
  include TestHelpers
  def setup
    @trip = trips(:one)
    @invoice = invoices(:one)
  end

  test 'trip can save' do
    trip = initialize_sample_trip
    assert trip.save, "Error message: #{trip.errors.full_messages}"
  end

  test "one invoice can have multiple trips" do
    trip1 = initialize_sample_trip
    @invoice.trips.push(trip1)
    @invoice.save
    trip2 = initialize_sample_trip(
      depart_airport: ICN, arrive_airport: "XYZ"
    )
    @invoice.trips.push(trip)
    @invoice.save
    assert @invoice.trips.size > 1
  end

This can be considered a "factory" design pattern. There are also various gems which can assist with this such as factory_girl or faker.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.