lost9123193
lost9123193

Reputation: 11040

Testing a method in Rails

I'm writing my first test in rails and I have a method which checks if the name passed through the animal object is valid. (Will return the name if valid or nil if not)

animal_verifier.rb

# frozen_string_literal: true

    class AnimalVerifier
      def initialize(last_sync_at, force_sync_ids)
        @last_sync_at = last_sync_at
        @force_sync_ids = force_sync_ids
      end

      def valid_animals
        animals.each do |animal|
          if !is_valid_animal(animal.name)
            Rails.logger.info("Invalid animal name")
            next
          end
        end
      end

      def is_valid_animal(animal_name)
        animal = AnimalFinder.find(animal_name)
      end

    end

animal_verifier_test.rb

require 'test_helper'

class AnimalVerifierTest < ActiveSupport::TestCase

  test "valid animal" do
    valid_animal = @is_valid_animal.send("Beluga")
    assert valid_animal?, "valid animal"
    puts valid_animal.errors unless valid_animal.errors.empty?
  end

  test "invalid animal" do
    valid_animal = @is_valid_animal.send("Puddle")
    assert valid_animal?, "invalid animal"
    puts valid_animal.errors unless valid_animal.errors.empty?
  end
end

When I run this test I get the error:

NoMethodError:         NoMethodError: undefined method `Beluga' for nil:NilClass

Does this mean I don't have a class for AnimalVerifier? I just want to test the specific method.

Upvotes: 1

Views: 28

Answers (1)

mrzasa
mrzasa

Reputation: 23347

@is_valid_animal is never initialized in your test, so it's nil, that's why you see the error undefined method ... for nil:NilClass. You should create an object under test first and then call methods on that.

When you call object.send("Beluga"), a message "Beluga" is sent to the object and it tries to invoke a method named Beluga. If it fails to find it in default case it raises an error of undefined method Beluga

Your test should look more like:

  test "valid animal" do
    verifier = AnimalVerifier.new(last_sync_at, force_sync_ids) # you need to init those thow params that are passed to the constructor
    valid_animal = verifier.is_valid_animal("Beluga")
    assert valid_animal, "valid animal"
    puts valid_animal.errors unless valid_animal.errors.empty?
  end

Note that I removed the question marks that were appended to method and variable names.

Upvotes: 1

Related Questions