首页 > 解决方案 > 如何在 Ruby 0n 中调用不是类实例的函数

问题描述

我是一名 Ruby 初学者,正在构建一个由 minitests 引导的简单 ruby​​ 博客应用程序,最初所有测试都已编写,所以我只确保我的代码运行所有测试。

从错误中我无法调用不是类实例的方法。

这里是测试

# build a blog console application and make the tests pass
# Have one file for the app (app.rb), 
# one file fo the runner (main.rb) 
# and this test file (test_blog.rb).
# when you run 

# ruby ./main.rb

# it should run the test and pass


class TestBlogApp < Minitest::Test
  def setup
    @blog = Blog.new(name: 'The best Blog')
  end

  def test_new_blog

    refute_nil @blog.id, 'id is initialized automatically'
    assert_equal @blog.name, 'The best Blog'
    assert_equal @blog.articles, [] 
    @blog.name = 'New Name'
    assert_equal @blog.name, 'New Name', 'Can edit field'
    assert_raises NoMethodError, 'id cannot be assigned' do
      @blog.id = 'new_id'
    end 
    assert_raises ArgumentError, 'nil not allowed' do
      Blog.new
    end  
  end

  def test_new_article
    title = 'Arcticle 1'
    body = 'Article 1 body'
    article_1 = @blog.new_article(title: title, body: body)
    refute_nil article_1.id, 'id is initialized automatically'
    assert_equal article_1.title, title
    assert_equal article_1.body, body
    assert_equal article_1.comments, []
    article_1.title = 'New Title'
    assert_equal article_1.title, 'New Title', 'Can edit field'
    article_1.body = 'New Body'
    assert_equal article_1.body, 'New Body', 'Can edit field'
    assert_raises NoMethodError, 'id cannot be assigned' do
      article_1.id = 'new_id'
    end
    assert_raises ArgumentError, 'nil not allowed' do
      Article.new
    end 
  end

  def test_articles_array
    2.times do
      @blog.new_article(title:'Article', body: 'Article body')
    end
    assert_equal @blog.articles.size, 2
  end

  def test_new_comments
    article = @blog.new_article(title:'Article', body: 'Article body')
    comment_body = 'This is great'
    comment = article.new_comment(body: comment_body)
    refute_nil comment.id, 'id is initialized automatically'
    assert_equal comment.body, comment_body
    comment.body = 'New Body'
    assert_equal comment.body, 'New Body', 'Can edit field'
    assert_raises NoMethodError, 'id cannot be assigned' do
      comment.id = 'new_id'
    end
    assert_raises ArgumentError, 'nil not allowed' do
      Comment.new
    end 
  end

  def test_comments_array
    article = @blog.new_article(title:'Article', body: 'Article body')
    2.times do
      article.new_comment(body: 'This is great')
    end
    assert_equal article.comments.size, 2
  end
end

下面是我的代码

require 'minitest/autorun'
require 'minitest/spec'
require 'minitest/pride'
require_relative 'test_blog'

class Blog
attr_accessor:name,:articles
attr_reader:id 

def initialize(name:)
@name=name
@id=rand(1..100)
@articles=[]
end 

def new_article(title:, body:)
articles << title 

{
  'id'=>rand(1..100).to_s,
  'title'=>title,
  'body'=>body,
}

end


end

#blog=Blog.new(name:'the best blog')
#p blog.name


#article_1=blog.new_article(title:'ruby arguments',body:'balalalalalala')
#p article_1.id

最后错误越来越多

ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]

Run options: --seed 32368

# Running:

*E*EE

Fabulous run in 0.003594s, 1391.2285 runs/s, 1947.7199 assertions/s.

  1) Error:
TestBlogApp#test_new_article:
NoMethodError: undefined method `id' for {"id"=>"88", "title"=>"Arcticle 1", "body"=>"Article 1 body"}:Hash
    /home/runner/test_blog.rb:36:in `test_new_article'

  2) Error:
TestBlogApp#test_comments_array:
NoMethodError: undefined method `new_comment' for {"id"=>"47", "title"=>"Article", "body"=>"Article body"}:Hash
    /home/runner/test_blog.rb:78:in `block in test_comments_array'
    /home/runner/test_blog.rb:77:in `times'
    /home/runner/test_blog.rb:77:in `test_comments_array'

  3) Error:
TestBlogApp#test_new_comments:
NoMethodError: undefined method `new_comment' for {"id"=>"45", "title"=>"Article", "body"=>"Article body"}:Hash
    /home/runner/test_blog.rb:62:in `test_new_comments'

5 runs, 7 assertions, 0 failures, 3 errors, 0 skips
exit status 1

标签: ruby

解决方案


在 ruby​​ 中,您不能使用点表示法访问散列中的键/值(与 javascript 不同)。更改您对该方法的访问权限article['id']或从该方法返回正确的 Article 对象。


推荐阅读