简体   繁体   English

如何使用 RSpec 测试“初始化”方法

[英]How to test "initialize" method using RSpec

github_asset.rb github_asset.rb

# frozen_string_literal: true

require 'asset_ingester/helpers/project_details'
require 'active_model'

module AssetIngester
  module Asset
    class GithubAsset
      include ActiveModel::Serializers::JSON

      attr_reader :id, :name, :full_name, :description, :owner_name, :owner_url,
                  :owner_avatar_url, :url, :html_url, :artifact_id, :jiras, :asset_type

      # Public: Initializes an instance of the GithubAsset class
      #
      # repo        - A hash containing github repository details
      # asset_type  - A string representation of the asset type
      def initialize(repo, asset_type)
        @id = repo[:id]
        @name = repo[:name]
        @full_name = repo[:full_name]
        @description = repo[:description]
        @owner_name = repo.dig(:owner, :login)
        @owner_url = repo.dig(:owner, :url)
        @owner_avatar_url = repo.dig(:owner, :avatar_url)
        @url = repo[:url]
        @html_url = repo[:html_url]
        @asset_type = asset_type
        @artifact_id = repo[:artifact_id] if repo[:artifact_id] && !repo[:artifact_id].empty?
        @jiras = repo[:jiras] if repo[:jiras] && !repo[:jiras].empty?
      end

      # Public: Defines the JSON serialization structure
      #
      # https://edgeguides.rubyonrails.org/active_model_basics.html#serialization
      def attributes
        {
          'id' => @id,
          'name' => @name,
          'full_name' => @full_name,
          'description' => @description,
          'owner_name' => @owner_name,
          'owner_url' => @owner_url,
          'owner_avatar_url' => @owner_avatar_url,
          'url' => @url,
          'html_url' => @html_url,
          'asset_type' => @asset_type,
          'artifact_id' => @artifact_id,
          'jiras' => @jiras
        }.compact
      end
    end
  end
end

github_asset_spec.rb github_asset_spec.rb

require 'asset_ingester/asset/github_asset'

RSpec.describe AssetIngester::Asset::GithubAsset, type: :api do
    context "creating" do 
        let(:asset_type) {"node_package"}
        let(:repo) do
            [id: 131_690,
                name: 'acm-care-management-js',
                full_name: 'AcuteCaseManagementUI/acm-care-management-js',
                owner_name: 'AcuteCaseManagementUI',
                owner_url: 'https://github.cerner.com/api/v3/users/AcuteCaseManagementUI',
                owner_avatar_url: 'https://avatars.github.cerner.com/u/4095?',
                url: 'https://github.cerner.com/api/v3/repos/AcuteCaseManagementUI/acm-care-management-js',
                html_url: 'https://github.cerner.com/AcuteCaseManagementUI/acm-care-management-js',
                asset_type: 'node_package',
                artifact_id: "",
                jiras: [] ]
            end

        describe '::attributes' do
            subject { AssetIngester::Asset::GithubAsset.attributes(repo, asset_type) }

            it 'instantiates the class with 2 arguments' do
              expect(subject).to be_an_instance_of(AssetIngester::Asset::GithubAsset)
            end

            it 'sets a to the first argument' do
              expect(subject.repo).to eq(repo)
            end

            it 'sets b to the second argument' do
              expect(subject.asset_type).to eq(asset_type)
            end
          end
    end
end

This is how i tried testing the github_asset.rb file but however I'am receiving the following error while defining the subject这就是我尝试测试 github_asset.rb 文件的方式,但是我在定义主题时收到以下错误

AssetIngester::Asset::GithubAsset creating ::attributes instantiates the class with 2 arguments Failure/Error: subject { AssetIngester::Asset::GithubAsset.attributes(repo, asset_type) } AssetIngester::Asset::GithubAsset 创建 ::attributes 使用 2 个参数实例化类失败/错误:subject { AssetIngester::Asset::GithubAsset.attributes(repo, asset_type) }

 NoMethodError:
   undefined method `attributes' for AssetIngester::Asset::GithubAsset:Class
   Did you mean?  attr_writer

I am green to RSpec testing and want to know how this can be done.我对 RSpec 测试持绿色态度,想知道如何做到这一点。

You get that NoMethodError because you are trying to call attributes as a class method :您得到NoMethodError是因为您试图将attributes作为类方法调用:

subject { AssetIngester::Asset::GithubAsset.attributes(repo, asset_type) }
#                                           ^^^^^^^^^^

although in your code, attributes is defined as an instance method .尽管在您的代码中, attributes被定义为实例方法

But apart from that, you ask "how ruby initialize method can be tested" and apparently your test code is all about initialize and not about attributes , so let's start at the beginning:但除此之外,您会问“如何测试 ruby​​ initialize 方法” ,显然您的测试代码都是关于initialize而不是关于attributes ,所以让我们从头开始:

describe '::attributes' do
  # ...
end

You want to test initialize, so attributes should be initialize .你想测试initialize,所以attributes应该是initialize And since initialize is an instance method (rather than a class method), :: should be # :由于initialize是一个实例方法(而不是类方法), ::应该是#

describe '#initialize' do
  # ...
end

And your subject should be an instance of GithubAsset which is created via new 1 :你的subject应该是GithubAsset一个实例,它是通过new 1创建的:

describe '#initialize' do
  subject { AssetIngester::Asset::GithubAsset.new(repo, asset_type) }

  # ...
end

With that in place, you can start writing your tests, eg:有了它,您就可以开始编写测试,例如:

describe '#initialize' do
  subject { AssetIngester::Asset::GithubAsset.new(repo, asset_type) }

  it 'sets the id attribute' do
    expect(subject.id).to eq(131690)
  end
end

1 In Ruby, you rarely invoke ::allocate and #initialize directly. 1在 Ruby 中,您很少直接调用::allocate#initialize So instead of:所以而不是:

obj = Array.allocate
obj.send(:initialize, 5) { |i| i ** 2 }
obj #=> [0, 1, 4, 9, 16]

you typically just call new and let it call allocate and initialize for you:您通常只需调用new并让它为您调用allocateinitialize

obj = Array.new(5) { |i| i ** 2 }
obj #=> [0, 1, 4, 9, 16]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM