Mocha está diseñado para usarse en pruebas unitarias para los tipos Mock Object o Test Stub de Test Double, no para los tipos Fake Object o Test Spy. Aunque sería posible ampliar Mocha para permitir la implementación de falsificaciones y espías, hemos optado por mantenerlo centrado en simulaciones y stubs.
Instale la última versión de la gema con el siguiente comando...
$ gem install mocha
Nota: Si tiene la intención de utilizar Mocha con Test::Unit o Minitest, solo debe configurar Mocha después de cargar la biblioteca de prueba correspondiente...
require 'rubygems'
gem 'mocha'
require 'test/unit'
require 'mocha/test_unit'
require 'rubygems'
gem 'mocha'
require 'minitest/autorun'
require 'mocha/minitest'
Si está utilizando Bundler, incluya Mocha en Gemfile
y luego configure Mocha más tarde una vez que sepa que la biblioteca de prueba se ha cargado...
# 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 incluye un adaptador moca. Simplemente dile a RSpec que quieres burlarte con :mocha
:
# Gemfile in Rails app
gem 'mocha'
# Within `spec/spec_helper.rb`
RSpec . configure do | config |
config . mock_with :mocha
end
Nota: No es necesario utilizar una declaración require para configurar Mocha; RSpec lo hace por sí mismo.
# 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
Si está cargando Mocha usando Bundler dentro de una aplicación Rails, debe configurar Mocha manualmente, por ejemplo, en la parte inferior de su test_helper.rb
.
Tenga en cuenta que desde Rails v4 (al menos), ActiveSupport::TestCase
ha heredado de Minitest::Test
o sus equivalentes anteriores. Por lo tanto, a menos que esté utilizando explícitamente Test::Unit, es probable que esté utilizando Minitest.
# Gemfile in Rails app
gem 'mocha'
# At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
require 'mocha/minitest'
Siga las instrucciones para el marco de prueba correspondiente en la sección Bundler, pero asegúrese de que el archivo Mocha correspondiente ( mocha/minitest
, mocha/test_unit
o mocha/api
) sea necesario después de que se haya cargado el marco de prueba, por ejemplo, en la parte inferior de test_helper.rb
o spec_helper.rb
, o al menos después de que se haya requerido rails/test_help
.
extend
la clase no funciona en Ruby v1.8. Consulte test/acceptance/stub_method_defined_on_module_and_aliased_test.rb
para ver un ejemplo de este comportamiento. 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 actualmente no intenta ser seguro para subprocesos.
La respuesta corta es no. En el código de subprocesos múltiples, las excepciones de Mocha pueden generarse en un subproceso distinto del que está ejecutando la prueba y, por lo tanto, es posible que el código de manejo de excepciones de Mocha no intercepte correctamente una excepción de Mocha.
Quizás, pero probablemente no. La burla parcial cambia el estado de los objetos en el ObjectSpace
que se comparte entre todos los subprocesos del proceso Ruby y este acceso a lo que efectivamente es un estado global no está sincronizado. Entonces, por ejemplo, si se ejecutan dos pruebas al mismo tiempo y una usa #any_instance
para modificar una clase, ambas pruebas verán esos cambios inmediatamente.
Los talones y las expectativas son básicamente lo mismo. Un talón es solo una expectativa de cero o más invocaciones. El método Expectation#stubs
es azúcar sintáctico para hacer más explícita la intención de la prueba.
Cuando se invoca un método en un objeto simulado, el objeto simulado busca entre sus expectativas, desde las más nuevas hasta las más antiguas, para encontrar una que coincida con la invocación. Después de la invocación, la expectativa de coincidencia podría dejar de coincidir con más invocaciones.
Consulte la documentación de Mocha::Mock
para obtener más detalles.
Si lo desea, Mocha puede generar una advertencia o generar una excepción cuando:
Consulte la documentación de Mocha::Configuration
para obtener más detalles.
MOCHA_OPTIONS
es una variable de entorno cuyo valor se puede establecer en una lista separada por comas, de modo que podamos especificar múltiples opciones, por ejemplo, MOCHA_OPTIONS=debug,use_test_unit_gem
. Actualmente sólo se reconocen y tienen efecto los siguientes valores:
debug
: habilita un modo de depuración que generará seguimientos para cada advertencia de obsolescencia. Esto es útil para encontrar en qué parte del conjunto de pruebas se encuentran las llamadas obsoletas.Vea esta lista de contribuyentes.
Actualice el archivo RELEASE.md con un resumen de cambios
Mejora la versión en lib/mocha/version.rb
Comprometerse y enviarse a GitHub
Verifique que la compilación de CircleCI esté pasando: https://app.circleci.com/pipelines/github/freerange/mocha
Generar documentación:
$ 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 se cosechó inicialmente en proyectos de Reevoo. Su sintaxis se basa en gran medida en la de jMock.
© Copyright James Mead 2006
Puede utilizar, copiar y redistribuir esta biblioteca bajo los mismos términos que Ruby o bajo la licencia MIT.