[英]How to test "initialize" method using RSpec
# 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
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
并让它为您调用allocate
和initialize
:
obj = Array.new(5) { |i| i ** 2 }
obj #=> [0, 1, 4, 9, 16]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.