2016-06-27 241 views
0

关注我有一个用于身份验证以下控制器关注:RSpec的3.4测试控制器与response.body.read

module ValidateEventRequest 
    extend ActiveSupport::Concern 

    def event_request_verified?(request) 
    sha256 = OpenSSL::Digest::SHA256.new 
    secret = app_client_id 
    body = request.body.read 
    signature = OpenSSL::HMAC.hexdigest(sha256, secret, body) 
    ([signature] & [request.headers['X-Webhook-Signature'], request.headers['X-Api-Signature']]).present? 
    end 

    private 

    def app_client_id 
    ENV['APP_CLIENT_ID'] 
    end 
end 

到目前为止,我有以下Rspec的测试设置,以达到此:

RSpec.describe ValidateEventRequest, type: :concern do 
    let!(:current_secret) { SecureRandom.hex } 

    describe '#event_request_verified?' do 
    it 'validates X-Webhook-Signature' do 
     # TBD 
    end 

    it 'validates X-Api-Signature' do 
     # TBD 
    end 
    end 
end 

我开始剔除这个请求,然后嘲笑和扼杀,现在我要摧毁我拥有的东西并寻求帮助。 100%的覆盖率对我来说很重要,我正在寻找一些关于如何构建涵盖这100%的测试的指针。

+0

所以看起来你学会了比从测试设置轨道以外的语言测试。在rspec中,您不需要以这种方式制作假货。你可以做“RSpec.describe ValidateEventRequest,输入::concern do”而不是创建一个假的。我不太了解如何测试问题,因为Ruby社区中的许多人认为他们是一个糟糕的想法(http://blog.coreyhaines.com/2012/12/why-i-dont-use-activesupportconcern.html,http ://mcdowall.info/the-great-satan-rails-concerns/)。这就是说,如果你像我提到的那样重构你的测试,你应该能够按照预期模拟和存根。 –

+0

我第一次尝试这种方式,并且无法得到存根和嘲笑正常工作....嗯.. –

+0

如果您想更新您的问题与您的旧代码,并让我知道您的具体错误信息,我可以帮助你通过它。就我个人而言,我认为你不需要担心这个问题,我只会采取一个行动之前。 –

回答

0

这是我如何解决这个问题,我打开思路:

RSpec.describe ValidateApiRequest, type: :concern do 
    let!(:auth_secret) { ENV['APP_CLIENT_ID'] } 
    let!(:auth_sha256) { OpenSSL::Digest::SHA256.new } 
    let!(:auth_body) { 'TESTME' } 
    let(:object) { FakeController.new } 
    before(:each) do 
    allow(described_class).to receive(:secret).and_return(auth_secret) 
    class FakeController < ApplicationController 
     include ValidateApiRequest 
    end 
    end 

    after(:each) do 
    Object.send :remove_const, :FakeController 
    end 

    describe '#event_request_verified?' do 
    context 'X-Api-Signature' do 
     it 'pass' do 
     request = OpenStruct.new(headers: { 'X-Api-Signature' => OpenSSL::HMAC.hexdigest(auth_sha256, auth_secret, auth_body) }, raw_post: auth_body) 
     expect(object.event_request_verified?(request)).to be_truthy 
     end 

     it 'fail' do 
     request = OpenStruct.new(headers: { 'X-Api-Signature' => OpenSSL::HMAC.hexdigest(auth_sha256, 'not-the-same', auth_body) }, raw_post: auth_body) 
     expect(object.event_request_verified?(request)).to be_falsey 
     end 
    end 

    context 'X-Webhook-Signature' do 
     it 'pass' do 
     request = OpenStruct.new(headers: { 'X-Webhook-Signature' => OpenSSL::HMAC.hexdigest(auth_sha256, auth_secret, auth_body) }, raw_post: auth_body) 
     expect(object.event_request_verified?(request)).to be_truthy 
     end 

     it 'fail' do 
     request = OpenStruct.new(headers: { 'X-Webhook-Signature' => OpenSSL::HMAC.hexdigest(auth_sha256, 'not-the-same', auth_body) }, raw_post: auth_body) 
     expect(object.event_request_verified?(request)).to be_falsey 
     end 
    end 
    end 
end 
0

object_double是非常方便的测试关注:

require 'rails_helper' 

describe MyClass do 
    subject { object_double(Class.new).tap {|c| c.extend MyClass} } 

    it "extends the subject" do 
    expect(subject.respond_to?(:some_method_in_my_class)).to be true 
    # ... 

然后你就可以测试subject像任何其他类。当然你需要在测试方法时传递适当的参数,这可能意味着创建额外的模拟 - 在你的情况下是请求对象。

+0

我喜欢这里要去的地方,你能否适应你的例子到我发布的代码中? –

+0

感谢您的帮助 –