2014-04-14 2 views
2

내가 원하는 mock a class with Ruby.루비 : const_set 외부 블록?

상용구 코드를 처리 할 방법을 어떻게 작성합니까?

다음 코드 :

module Mailgun 

end 

module Acani 
    def self.mock_mailgun(mock) 
    temp = Mailgun 
    const_set(:Mailgun, mock) 
    p Mailgun 
    yield 
    ensure 
    const_set(:Mailgun, temp) 
    end 
end 

Acani.mock_mailgun('mock') { p Mailgun } 

지문 :

"mock" 
Mailgun 

여기 무슨 일이야? Mailgun가 블록 내부의 원래 값인 이유는 무엇입니까? 이것은 Ruby 바인딩과 관련이 있습니까?

루비 버전 : 각 const_set 전에 Object. 퍼팅 2.1.1p76

답변

0

보십시오.

질문의 코드가 단순화되었습니다.

테스트/test_helper.rb

require 'minitest/autorun' 

module Acani 
    def self.const_mock(const, mock) 
    temp = const_get(const) 
    const_set_silent(const, mock) 
    yield 
    ensure 
    const_set_silent(const, temp) 
    end 

    private 

    def self.const_set_silent(const, value) 
    temp = $VERBOSE 
    $VERBOSE = nil 
    Object.const_set(const, value) 
    ensure 
    $VERBOSE = temp 
    end 
end 

시험/web_test.rb

require 'test_helper' 
require 'rack/test' 
require_relative '../web' 

class AppTest < MiniTest::Test 
    include Rack::Test::Methods 

    def app 
    Sinatra::Application 
    end 

    def test_password_reset 
    post '/users', {email: '[email protected]', password: 'password1'} 

    mailgun_mock = MiniTest::Mock.new 
    mailgun_mock.expect(:send, 200, [Hash]) 

    Acani.const_mock(:Mailgun, mailgun_mock) do 
     post '/password_resets', {email: '[email protected]'} 
    end 

    mailgun_mock.verify 
    assert_equal 201, last_response.status 
    end 
end 
다음은 관련 코드는