2017-08-02 78 views
3

所以这是一个简短的教程,我发现abouot Rspec:w3ii.com: rspec它是关于rspec helpers的解释。这是该示例代码:为什么ruby为方法调用返回`true`?

class Dog 
    attr_reader :good_dog, :has_been_walked 

    def initialize(good_or_not) 
     @good_dog = good_or_not 
     @has_been_walked = false 
    end 

    def walk_dog 
     @has_been_walked = true 
    end 
end 

describe Dog do 
    def create_and_walk_dog(good_or_bad) 
     Dog.new(good_or_bad).walk_dog 
    end 

    it 'should be able to create and walk a good dog' do 
     dog = create_and_walk_dog(true) 

     expect(dog.good_dog).to be true 
     expect(dog.has_been_walked).to be true 
    end 
end 

当我运行它,我得到这个错误:

NoMethodError: undefined method 'good_dog' for true:TrueClass
# ./dor.rb:22:in 'block <2 levels> in >'

我不明白Dog.new()的调用如何返回真: TrueClass对象而不是简单的狗。

+1

我会超级小心使用w3ii作为参考网站,因为它看起来相当低质量。有更好的[开始](https://en.wikipedia.org/wiki/Programming_Ruby)。 – tadman

回答

3

这是因为create_and_walk_dog回报的walk_dog方法返回

要从create_and_walk_dog方法,你需要像

describe Dog do 
    def create_and_walk_dog(good_or_bad) 
     dog = Dog.new(good_or_bad) 
     dog.walk_dog 
     dog 
    end 

    it 'should be able to create and walk a good dog' do 
     dog = create_and_walk_dog(true) 

     expect(dog.good_dog).to be true 
     expect(dog.has_been_walked).to be true 
    end 
end 

或延长期望块返回狗:

describe Dog do 
    it 'should be able to create and walk a good dog' do 
     dog = Dog.new(true) 

     expect(dog.good_dog).to be true 
     expect { 
     dog.walk_dog 
     }.to change(dog, :has_been_walked).from(false).to true 
    end 
end 
+2

您还可以通过将'self'作为最后一行代码添加到'walk_dog'链接方法中。 – tadman

+2

这将是一个很好的例子,使用'tap(&:block)'方法,该方法产生给定的block,然后返回对象本身。在这种情况下:'Dog.new(good_or_bad).tap(&:walk_dog)' – MrYoshiji

0

我想清楚你可以/应该使用RSpec let方法不是RSpec文件中包含的完整方法定义。让您的_walk_dog_方法返回自我,就像我在这里看到的另一个答案中的建议一样修复您当前的RSpec实现,但不会帮助您在潜在应用程序中的任何其他位置流动。假设情况不好狗回报false为_dog.walk_dog_随机50%或只是不合作。

class Dog 
    attr_reader :good_dog, :has_been_walked 

    def initialize(good_or_not) 
    @good_dog = good_or_not 
    @has_been_walked = false 
    end 

    # Command to attempt walking a dog. 
    # 
    # @api public 
    # 
    # @example 
    # good_dog = Dog.new(true) 
    # good_dog.walk_dog # => Will always return true for good dogs. 
    # bad_dog = Dog.new(false) 
    # bad_dog.wal_dog # => 50/50 chance of true or false 
    def walk_dog 
    return @has_been_walked = true if @good_dog 
    [true, false].sample 
    end 
end 

describe Dog do 

    let(:good_dog) { Dog.new(true) } 

    it 'should always be able to walk a good dog' do 
    expect(good_dog.walk_dog).to be true 
    end 

    it 'should track if the dog has been walked' do 
    expect { 
     good_dog.walk_dog 
    }.to change(dog, :has_been_walked).from(false).to true 
    end 

end 

为辩论还,但你只应还声称按规格一件事,除非你打的DB或做一些比较耗时。

P.S.他们都是好狗布伦特

相关问题