Mocha는 Fake Object 또는 Test Spy 유형이 아닌 Test Double의 Mock Object 또는 Test Stub 유형에 대한 단위 테스트에 사용되도록 고안되었습니다. 가짜와 스파이 구현을 허용하도록 Mocha를 확장하는 것이 가능하더라도 우리는 모카와 스텁에 계속 초점을 맞추기로 결정했습니다.
다음 명령을 사용하여 최신 버전의 gem을 설치하십시오...
$ gem install mocha
참고: Test::Unit 또는 Minitest와 함께 Mocha를 사용하려는 경우 관련 테스트 라이브러리를 로드한 후에 만 Mocha를 설정해야 합니다.
require 'rubygems'
gem 'mocha'
require 'test/unit'
require 'mocha/test_unit'
require 'rubygems'
gem 'mocha'
require 'minitest/autorun'
require 'mocha/minitest'
Bundler를 사용하는 경우 Gemfile
에 Mocha를 포함시킨 다음 나중에 테스트 라이브러리가 로드되었음을 확인한 후 Mocha를 설정하세요.
# Gemfile
gem 'mocha'
# Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
require 'test/unit'
require 'mocha/test_unit'
# Gemfile
gem 'mocha'
# Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
require 'minitest/autorun'
require 'mocha/minitest'
RSpec에는 모카 어댑터가 포함되어 있습니다. 그냥 RSpec에게 :mocha
로 모의하고 싶다고 말하세요.
# Gemfile in Rails app
gem 'mocha'
# Within `spec/spec_helper.rb`
RSpec . configure do | config |
config . mock_with :mocha
end
참고: Mocha를 설정하기 위해 require 문을 사용할 필요는 없습니다. RSpec은 이 작업을 자체적으로 수행합니다.
# In e.g. features/support/mocha.rb
require 'mocha/api'
World ( Mocha :: API )
Around do | scenario , block |
begin
mocha_setup
block . call
mocha_verify
ensure
mocha_teardown
end
end
Rails 애플리케이션 내에서 Bundler를 사용하여 Mocha를 로드하는 경우, 예를 들어 test_helper.rb
하단에서 Mocha를 수동으로 설정해야 합니다.
Rails v4(적어도)부터 ActiveSupport::TestCase
Minitest::Test
또는 이전 버전에서 상속되었습니다. 따라서 Test::Unit을 명시적으로 사용하지 않는 한 Minitest를 사용할 가능성이 높습니다.
# Gemfile in Rails app
gem 'mocha'
# At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
require 'mocha/minitest'
번들러 섹션의 관련 테스트 프레임워크에 대한 지침을 따르되, 테스트 프레임워크가 로드된 후 (예: test_helper.rb
하단에) 관련 Mocha 파일( mocha/minitest
, mocha/test_unit
또는 mocha/api
)이 필요한지 확인하세요. test_helper.rb
또는 spec_helper.rb
, 또는 최소한 rails/test_help
필요한 이후.
extend
데 사용되는 모듈에 원래 메서드가 정의된 별칭 클래스 메서드를 스텁하는 것은 Ruby v1.8에서 작동하지 않습니다. 이 동작의 예는 test/acceptance/stub_method_defined_on_module_and_aliased_test.rb
참조하세요. require 'test/unit'
require 'mocha/test_unit'
class MiscExampleTest < Test :: Unit :: TestCase
def test_mocking_a_class_method
product = Product . new
Product . expects ( :find ) . with ( 1 ) . returns ( product )
assert_equal product , Product . find ( 1 )
end
def test_mocking_an_instance_method_on_a_real_object
product = Product . new
product . expects ( :save ) . returns ( true )
assert product . save
end
def test_stubbing_instance_methods_on_real_objects
prices = [ stub ( pence : 1000 ) , stub ( pence : 2000 ) ]
product = Product . new
product . stubs ( :prices ) . returns ( prices )
assert_equal [ 1000 , 2000 ] , product . prices . collect { | p | p . pence }
end
def test_stubbing_an_instance_method_on_all_instances_of_a_class
Product . any_instance . stubs ( :name ) . returns ( 'stubbed_name' )
product = Product . new
assert_equal 'stubbed_name' , product . name
end
def test_traditional_mocking
object = mock ( 'object' )
object . expects ( :expected_method ) . with ( :p1 , :p2 ) . returns ( :result )
assert_equal :result , object . expected_method ( :p1 , :p2 )
end
def test_shortcuts
object = stub ( method1 : :result1 , method2 : :result2 )
assert_equal :result1 , object . method1
assert_equal :result2 , object . method2
end
end
class Enterprise
def initialize ( dilithium )
@dilithium = dilithium
end
def go ( warp_factor )
warp_factor . times { @dilithium . nuke ( :anti_matter ) }
end
end
require 'test/unit'
require 'mocha/test_unit'
class EnterpriseTest < Test :: Unit :: TestCase
def test_should_boldly_go
dilithium = mock ( )
dilithium . expects ( :nuke ) . with ( :anti_matter ) . at_least_once # auto-verified at end of test
enterprise = Enterprise . new ( dilithium )
enterprise . go ( 2 )
end
end
class Order
attr_accessor :shipped_on
def total_cost
line_items . inject ( 0 ) { | total , line_item | total + line_item . price } + shipping_cost
end
def total_weight
line_items . inject ( 0 ) { | total , line_item | total + line_item . weight }
end
def shipping_cost
total_weight * 5 + 10
end
class << self
def find_all
# Database.connection.execute('select * from orders...
end
def number_shipped_since ( date )
find_all . select { | order | order . shipped_on > date } . length
end
def unshipped_value
find_all . inject ( 0 ) { | total , order | order . shipped_on ? total : total + order . total_cost }
end
end
end
require 'test/unit'
require 'mocha/test_unit'
class OrderTest < Test :: Unit :: TestCase
# illustrates stubbing instance method
def test_should_calculate_shipping_cost_based_on_total_weight
order = Order . new
order . stubs ( :total_weight ) . returns ( 10 )
assert_equal 60 , order . shipping_cost
end
# illustrates stubbing class method
def test_should_count_number_of_orders_shipped_after_specified_date
now = Time . now ; week_in_secs = 7 * 24 * 60 * 60
order_1 = Order . new ; order_1 . shipped_on = now - 1 * week_in_secs
order_2 = Order . new ; order_2 . shipped_on = now - 3 * week_in_secs
Order . stubs ( :find_all ) . returns ( [ order_1 , order_2 ] )
assert_equal 1 , Order . number_shipped_since ( now - 2 * week_in_secs )
end
# illustrates stubbing instance method for all instances of a class
def test_should_calculate_value_of_unshipped_orders
Order . stubs ( :find_all ) . returns ( [ Order . new , Order . new , Order . new ] )
Order . any_instance . stubs ( :shipped_on ) . returns ( nil )
Order . any_instance . stubs ( :total_cost ) . returns ( 10 )
assert_equal 30 , Order . unshipped_value
end
end
Mocha는 현재 스레드로부터 안전해지려고 시도 하지 않습니다 .
짧은 대답은 '아니요'입니다. 다중 스레드 코드에서는 테스트를 실행하는 스레드가 아닌 다른 스레드에서 Mocha 예외가 발생할 수 있으므로 Mocha 예외 처리 코드가 Mocha 예외를 올바르게 가로채지 못할 수 있습니다.
어쩌면 아닐 수도 있습니다. 부분적 조롱은 Ruby 프로세스의 모든 스레드에서 공유되는 ObjectSpace
의 객체 상태를 변경하며 사실상 전역 상태에 대한 이러한 액세스는 동기화되지 않습니다. 예를 들어 두 개의 테스트가 동시에 실행 중이고 하나가 #any_instance
사용하여 클래스를 수정하는 경우 두 테스트 모두 해당 변경 사항을 즉시 확인할 수 있습니다.
스텁과 기대는 기본적으로 동일합니다. 스텁은 0개 이상의 호출을 기대하는 것입니다. Expectation#stubs
메소드는 테스트 의도를 더욱 명확하게 하기 위한 구문적 설탕입니다.
모의 개체에서 메서드가 호출되면 모의 개체는 호출과 일치하는 항목을 찾기 위해 최신 항목부터 가장 오래된 항목까지 기대치를 검색합니다. 호출 후에는 일치 기대치가 추가 호출 일치를 중지할 수 있습니다.
자세한 내용은 Mocha::Mock
설명서를 참조하세요.
원하는 경우 Mocha는 다음과 같은 경우에 경고를 생성하거나 예외를 발생시킬 수 있습니다.
자세한 내용은 Mocha::Configuration
설명서를 참조하세요.
MOCHA_OPTIONS
는 값을 쉼표로 구분된 목록으로 설정할 수 있는 환경 변수이므로 MOCHA_OPTIONS=debug,use_test_unit_gem
과 같은 여러 옵션을 지정할 수 있습니다. 현재는 다음 값만 인식되고 영향을 미칩니다.
debug
: 각 지원 중단 경고에 대한 역추적을 출력하는 디버그 모드를 활성화합니다. 이는 테스트 스위트에서 더 이상 사용되지 않는 호출이 있는 위치를 찾는 데 유용합니다.이 기여자 목록을 참조하세요.
변경 사항 요약으로 RELEASE.md 파일 업데이트
lib/mocha/version.rb
에서 버전을 확인하세요.
GitHub에 커밋 및 푸시
CircleCI 빌드가 통과하는지 확인하세요 - https://app.circleci.com/pipelines/github/freerange/mocha
문서 생성:
$ MOCHA_GENERATE_DOCS=true bundle install
$ MOCHA_GENERATE_DOCS=true rake generate_docs
$ curl -u < email-address > -H ' OTP: ' https://rubygems.org/api/v1/api_key.yaml > ~ /.gem/credentials ; chmod 0600 ~ /.gem/credentials
$ rake release
[runs tests]
mocha 1.2.0 built to pkg/mocha-1.2.0.gem.
Tagged v1.2.0.
Pushed git commits and tags.
Pushed mocha 1.2.0 to rubygems.org.
Mocha는 처음에 Reevoo의 프로젝트에서 수확되었습니다. 이 구문은 jMock의 구문을 기반으로 합니다.
© 저작권 제임스 미드 2006
귀하는 Ruby 자체와 동일한 조건 또는 MIT 라이선스에 따라 이 라이브러리를 사용, 복사 및 재배포할 수 있습니다.