小编Jay*_*rka的帖子

将类/模块恢复到原始状态

我想知道 RSpec 如何实现这一点:

expect( MyObject ).to receive(:the_answer).and_return(42)
Run Code Online (Sandbox Code Playgroud)

不RSpec的利用define_singleton_method注入:the_answerMyObject

那可以工作。让我们假设这是MyObject看起来的样子:

class MyObject
    def self.the_answer
        21 * 2
    end
end
Run Code Online (Sandbox Code Playgroud)

注入的 the_answer方法可能包含这样的事情:

@the_answer_called = true
42
Run Code Online (Sandbox Code Playgroud)

但是,RSpec 如何将类恢复到未模拟状态?它如何恢复它以便MyObject.the_answer“真正”再次返回 42 ?(通过 21 * 2)

自从写这个问题以来,我认为它没有。类方法保持模拟直到 RSpec 停止运行。

但是,(这是问题的关键)如何撤消define_singleton_method?

我认为最简单的方法是old_object = Object.dupdefine_singleton_method使用之前运行,但是,我如何恢复old_objectObject

当我想做的只是恢复一个类方法时,这也没有让我感到高效。虽然目前这不是一个问题,但也许将来我还想保持某些实例变量MyObject完好无损。是否有一种非hacky 的方式来复制代码 ( 21 * 2) 并将其重新定义为the_answerviadefine_singleton_method而不是完全替换Object

欢迎所有想法,我绝对想知道如何制作Object …

ruby rspec

5
推荐指数
1
解决办法
118
查看次数

只模拟一次方法

在替换原始的模拟方法之前,有没有办法模拟一个方法一次且每个期望只模拟一次?

我认为这样的事情会起作用(注意once

class Klass
    def self.meth
        'baz'
    end
end

describe Klass do
    subject{ described_class.meth }
    before{ allow(described_class).to receive(:meth).once.and_return('foo') }
    it{ is_expected.to eq 'foo' }
    context 'throwing in a context just to test' do
        it{ is_expected.to eq 'foo' }
        it{ is_expected.to eq 'foo' }
        it{ is_expected.to eq 'foo' }
        it 'only mocks once' do
            expect(subject).to eq 'foo'
            expect(subject).to eq 'baz' # this is the key
        end # pass
    end
end
Run Code Online (Sandbox Code Playgroud)

不幸的是,我收到此错误:

   (Klass (class)).meth(no args)
       expected: 1 time with any …
Run Code Online (Sandbox Code Playgroud)

rspec

3
推荐指数
1
解决办法
6443
查看次数

标签 统计

rspec ×2

ruby ×1