首页 > 解决方案 > 在 Rails 中测试方法

问题描述

我正在用 rails 编写我的第一个测试,我有一个方法可以检查通过动物对象的名称是否有效。(如果有效或无效,将返回名称nil

动物验证器.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

当我运行这个测试时,我得到了错误:

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

这是否意味着我没有课程AnimalVerifier?我只是想测试一下具体的方法。

标签: ruby-on-railsrubytesting

解决方案


@is_valid_animal在您的测试中从未初始化,所以它是nil,这就是您看到错误的原因undefined method ... for nil:NilClass。您应该首先创建一个被测对象,然后对其调用方法。

当您调用 时object.send("Beluga"),会向 发送消息“Beluga”,object并尝试调用名为 的方法Beluga。如果在默认情况下找不到它,则会引发错误undefined method Beluga

您的测试应该看起来更像:

  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

请注意,我删除了附加到方法和变量名称的问号。


推荐阅读