我可以模拟一个包含的模块吗?

时间:2014-02-04 06:03:51

标签: unit-testing rspec mocking

在明确包含模块时很容易模拟出来,如下所示:

class MyController < ApplicationController
    MyHelper.sometimes_true_sometimes_false
end

在规范中,您只需编写:

MyHelper.should_receive(:sometimes_true_sometimes_false).and_return true

在上下文中:

模块

module MyHelper
    def sometimes_true_sometimes_false
        [true, false].sample
    end
end

控制器

class MyController < ApplicationController
    def myaction
        if MyHelper.sometimes_true_sometimes_false
            @message = "Congratualtions, it's true"
        else
            @message = "Sorry, it's false"
        end
    end
end

规范

describe 'GET #myaction'
    subject { get :myaction }
    context 'when it\'s true' do
        before do
             MyHelper.should_receive(:sometimes_true_sometimes_false).and_return true
        end
        specify { expect(assigns(:message)).to eq "Congratulations, it's true" }
    end
    context 'when it\'s false' do
        before do
             MyHelper.should_receive(:sometimes_true_sometimes_false).and_return false
        end
        specify { expect(assigns(:message)).to eq "Sorry, it's true" }
    end
end

但是当模块包含在控制器中时,我应该如何编写规范,以及本机调用的类方法,如下所示:

class MyController < ApplicationController
    include MyHelper

    sometimes_true_sometimes_false
end

在上下文中:

控制器

class MyController < ApplicationController
    include MyHelper

    def myaction
        if sometimes_true_sometimes_false
            @message = "Congratualtions, it's true"
        else
            @message = "Sorry, it's false"
        end
    end
end

1 个答案:

答案 0 :(得分:0)

实际上非常简单,在我创建答案的同时想到了答案(并且使用标题标签进行了精神处理):

你只需写:

MyController.any_instance.should_receive(:sometimes_true_sometimes_false).and_return true

规范

describe 'GET #myaction'
    subject { get :myaction }
    context 'when it\'s true' do
        before do
             MyController.any_instance.should_receive(:sometimes_true_sometimes_false).and_return true
        end
        specify { expect(assigns(:message)).to eq "Congratulations, it's true" }
    end
    context 'when it\'s false' do
        before do
             MyController.any_instance.should_receive(:sometimes_true_sometimes_false).and_return false
        end
        specify { expect(assigns(:message)).to eq "Sorry, it's true" }
    end
end