RSpec: comment faire pour tester les Rails de l'enregistreur de message attentes?
Je suis en train de tester que les Rails enregistreur reçoit des messages dans certains de mes spécifications. Je suis l'aide de la La journalisation des gem.
Disons que j'ai une classe comme ceci:
class BaseWorker
def execute
logger.info 'Starting the worker...'
end
end
Et un spec comme:
describe BaseWorker do
it 'should log an info message' do
base_worker = BaseWorker.new
logger_mock = double('Logging::Rails').as_null_object
Logging::Rails.stub_chain(:logger, :info).and_return(logger_mock)
logger_mock.should_receive(:info).with('Starting the worker...')
base_worker.execute
Logging::Rails.unstub(:logger)
end
end
J'obtiens le message d'erreur:
Failure/Error: logger_mock.should_receive(:info).with('Starting worker...')
(Double "Logging::Rails").info("Starting worker...")
expected: 1 time
received: 0 times
J'ai essayé plusieurs approches différentes pour faire passer la spec. Cela fonctionne par exemple:
class BaseWorker
attr_accessor :log
def initialize
@log = logger
end
def execute
@log.info 'Starting the worker...'
end
end
describe BaseWorker do
it 'should log an info message' do
base_worker = BaseWorker.new
logger_mock = double('logger')
base_worker.log = logger_mock
logger_mock.should_receive(:info).with('Starting the worker...')
base_worker.execute
end
end
Mais d'avoir à l'installation accessible une variable d'instance, comme cela semble être la queue qui remue le chien ici. (En fait, je ne suis même pas sûr pourquoi, la copie de l'enregistreur vers @journal le faire passer.)
Ce qui est une bonne solution pour tester l'enregistrement?
Vous devez vous connecter pour publier un commentaire.
Alors que je suis d'accord en général, vous ne voulez pas tester les bûcherons, il y a des moments, il peut être utile.
J'ai eu du succès avec les attentes sur
Rails.logger
.À l'aide de RSpec obsolète
should
syntaxe:À l'aide de RSpec la plus récente de l'
expect
syntaxe:Remarque: Dans le contrôleur et les caractéristiques du modèle, vous devez mettre cette ligne avant le message est enregistré. Si vous mettez par la suite, vous obtiendrez un message d'erreur comme ceci:
expect(Rails.logger).to_not receive(:error).with(anything)
let
expressions avant lait
bloc court mêmeexpect(Rails.logger).to receive(:info).with(/foobar/)
, placé à l'avant de la spec code qui permettra de générer de l'enregistrement. Je peux clairement voir lafoobar
déclaration danstest.log
après le fonctionnement de la spec, mais la spec échoue avec l'erreur ci-dessus.Avec RSpec 3+ version
Code contenant un seul invocation de
Rails.logger.error
:Spec code:
Si vous souhaitez que le message d'erreur d'être connecté tout le fonctionnement de la spec puis utilisez le code suivant:
Code contenant de multiples appels de
Rails.logger.error
:Spec code:
Aussi, si vous vous souciez de la juste correspondance le premier message et de ne pas les messages suivants, alors vous pouvez utiliser la suite
Note au-dessus de variation réglage
.ordered
est important d'autre attentes commencer à échouer.Références:
http://www.relishapp.com/rspec/rspec-mocks/v/3-4/docs/setting-constraints/matching-arguments
http://www.relishapp.com/rspec/rspec-mocks/v/3-4/docs/setting-constraints/message-order
Si votre objectif est de tester la fonctionnalité de journalisation, vous pouvez également envisager de vérification de la sortie de flux standard.
Cela vous épargnera les moqueries de processus et de vérifier si des messages sera vraiment la fin là où ils l'avaient supposé (STDOUT/STDERR).
Avec RSpec est sortie matcher (introduit dans la version 3.0), vous pouvez effectuer les opérations suivantes:
Dans le cas de bibliothèques telles que
Logger
ouLogging
vous pourriez avoir à utiliseroutput.to_<>_from_any_process
.