首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测试#类作者的初始化

测试#类作者的初始化
EN

Code Review用户
提问于 2016-10-10 17:51:49
回答 3查看 2.1K关注 0票数 0

我正在尝试测试Author类的#初始化:

代码语言:javascript
复制
# lib/author.rb
class Author
  attr_reader :name, :filename, :website

  def initialize(name, filename, website)
    @name = name
    @filename = filename
    set_filename_from_name if filename == :auto
    @website = website
  end
end

实际上,Author有8-9个属性,而不仅仅是3个,我已经决定在#初始化中要求它们全部实现。

我正试图把我的规格弄干,但我有很多重复。

我创建了一个助手模块:

代码语言:javascript
复制
#spec/helpers/create_author.rb
module CreateAuthor
  # Creates author with default values except for those listed
  # under params.
  def create_author(params = {})
    defaults = {
      name: "Ford",
      filename: "Ford",
      website: 'www.ford.com'
    }
    opt = defaults.merge(params)

    Author.new(opt[:name],
      opt[:filename],
      opt[:website])
  end
end

但是现在我有了未经测试的代码,我需要进行测试。这是该助手方法的规范:

代码语言:javascript
复制
# spec/authors_helper_spec.rb
require_relative 'helpers/create_author'

describe 'Create Author Helper' do
  # subject do
  #   Class.new { include CreateAuthor }
  # end
  include CreateAuthor

  let(:defaults) do
    {
      name: "Ford",
      filename: "Ford",
      website: 'www.ford.com'
    }
  end


  describe '#create_author' do
    it 'returns author with default values when called with no parameters' do
      author = create_author()

      expect(author.class).to eq(Author)
      expect(author.name).to eq(defaults[:name])
      expect(author.filename).to eq(defaults[:filename])
      expect(author.website).to eq(defaults[:website])
    end

    it 'returns author with custom name when specified' do
      author = create_author(name: 'New Name')

      expect(author.class).to eq(Author)
      expect(author.name).to eq('New Name')
      expect(author.filename).to eq(defaults[:filename])
      expect(author.website).to eq(defaults[:website])          
    end
  end
end

我需要对其他类做类似的事情,所以我只需要将create_author(options={})更改为create_class(class, options={})并对其进行测试。

我怎么才能把它弄干,让它不那么冗长呢?

EN

回答 3

Code Review用户

发布于 2016-10-11 23:04:07

您可以使用以下解决方案,除非在"create_author“中调用初始化很重要。

代码语言:javascript
复制
# spec/helpers/create_author.rb
module CreateEntity
  def create_entity(klass, params = {}, defaults = {})
    opt = defaults.merge(params)

    entity = klass.allocate
    opt.each do |key, value|
      entity.instance_variable_set("@#{key}", value)
    end
    entity
  end

  def create_author(params = {})
    create_entity(Author, params, {
      name: "Ford",
      filename: "Ford",
      website: 'www.ford.com'
    })
  end
end

create_author(name: "Ford 1")
票数 1
EN

Code Review用户

发布于 2016-10-13 10:15:26

我会给大家举一个例子。它没有经过测试,但它应该像这样工作:

代码语言:javascript
复制
#spec/helpers/shares_examples/check_default_behaviour.rb

RSpec.shared_examples 'check default behaviour' do |class_to_instantiate|

  def create_instance(params = {})
    opt = defaults.merge(params)

    class_to_instantiate.new(opt[:name],
               opt[:filename],
               opt[:website])
  end

  # let(:defaults) has to be set within your spec

  describe "#create_#{class_to_instantiate}" do
    it "returns #{class_to_instantiate} with default values when called with no parameters" do
      instance = create_instance()

      expect(instance.class).to eq(class_to_instantiate)
      expect(instance.name).to eq(defaults[:name])
      expect(instance.filename).to eq(defaults[:filename])
      expect(instance.website).to eq(defaults[:website])
    end

    it "returns #{class_to_instantiate} with custom name when specified" do
      instance = create_instance(name: 'New Name')

      expect(instance.class).to eq(class_to_instantiate)
      expect(instance.name).to eq('New Name')
      expect(instance.filename).to eq(defaults[:filename])
      expect(instance.website).to eq(defaults[:website])
    end
  end
end

# spec/...
describe 'Create Author Helper' do
  let(:defaults) do
    {
        name: "Ford",
        filename: "Ford",
        website: 'www.ford.com'
    }
  end

  include_examples 'check default behaviour', Author
end
票数 0
EN

Code Review用户

发布于 2016-10-23 20:12:49

您应该尽可能地使您的测试用例依赖于共享代码。

这是一个更大的策略的一部分,以使更多的“可测试”代码。在您的主要应用程序中,如果您有三种类似的方法,并且想要100%的单元测试覆盖率,那么您必须对这三种方法进行测试。但是,如果您重构应用程序代码以使用一种方法,那么应用程序代码和测试都将更加简洁。

重申一下--仅仅是为了理智,如果你打算写100%的单元测试覆盖率,那么写“可测试的”代码是值得的--如果你的代码杂乱无章,就没有什么神奇的方法可以让你的测试套件变得简洁。

我可能是误解了,但是除了应用程序代码之外,您还想测试您的助手吗?这样做可能有点过分--人们真的在测试他们的测试套件吗?

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/143818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档