2015-07-30 8 views
7

Sto provando a utilizzare unittest per verificare alcune funzioni di un SimpleXMLRPCServer che ho creato. Togethere con Mock, sto cercando ora di affermare che è stato registrato un messaggio specifico quando viene raggiunta un'istruzione if, ma non riesco a farlo funzionare. Ho provato a implementare varie risposte che ho trovato qui su StackOverflow o su Google, ma ancora senza fortuna. Le chiamate che faccio nel caso di test sono le seguenti:Asserire che la registrazione sia stata chiamata con una stringa specifica

def test_listen_for_tasks(self): 
    el = {'release': 'default', 'component': None} 
    for i in range(50): 
     self.server._queue.put(el) 
    ServerThread.listen_for_tasks(self.server, 'bla', 'blabla') 
    with mock.patch('queue_server.logging') as mock_logging: 
     mock_logging.warning.assert_called_with('There are currently {}' 
               ' items in the queue'.format(
               str(len(self.server._queue.queue)))) 

La funzione del server è la seguente:

def listen_for_tasks(self, release, component): 
    item = {'release': release, 'component': component} 
    for el in list(self._queue.queue): 
     if self.is_request_duplicate(el, item): 
      logger.debug('Already have a request' 
         ' for this component: {}'.format(item)) 
      return 
    self._queue.put(item, False) 
    if len(self._queue.queue) > 50: 
     logger.warning('There are currently {}' 
         ' items in the queue'.format(
         str(len(self._queue.queue)))) 

Qualsiasi idea del perché questo non sta funzionando? Sono nuovo al test delle unità in Python e affermando che un logger ha fatto qualcosa sembra il problema più grande che si possa affrontare, quindi avrei potuto rovinare qualcosa di veramente semplice nel codice. Ogni tipo di aiuto sarà molto apprezzato!

EDIT: per completezza, ecco l'uscita di test e il fallimento:

.No handlers could be found for logger "queue_server" 
F 


FAIL: test_listen_for_tasks (__main__.TestQueueServer) 

Traceback (most recent call last): 
    File "artifacts_generator/test_queue_server.py", line 46, in test_listen_for_tasks 
str(len(self.server._queue.queue)))) 
    File "/home/lugiorgi/Desktop/Code/publisher/env/local/lib/python2.7/site-packages/mock/mock.py", line 925, in assert_called_with 
raise AssertionError('Expected call: %s\nNot called' % (expected,)) 
AssertionError: Expected call: warning('There are currently 51 items in the queue') 
Not called 

Ran 2 tests in 0.137s 

FAILED (failures=1) 

risposta

7

È necessario prima finto l'oggetto, quindi chiamata la funzione che si desidera eseguire il test.

Quando si deride l'oggetto, è necessario fornire anche il pacchetto completo e il nome oggetto/funzione dell'oggetto che si sta beffando, non un nome di variabile.

Infine, spesso è più comodo utilizzare il modulo decoratore patch.

Così, ad esempio:

logger = logging.getLogger(__name__) 

def my_fancy_function(): 
    logger.warning('test') 

@patch('logging.Logger.warning') 
def test_my_fancy_function(mock): 
    my_fancy_function() 
    mock.assert_called_with('test') 

# if you insist on using with: 
def test_my_fancy_function_with_with(): 
    with patch('logging.Logger.warning') as mock: 
     my_fancy_function() 
     mock.assert_called_with('test') 
+0

funziona come un fascino, grazie mille! –

+0

Dato che questo è taggato per Python 2.7, una risposta completa dovrebbe menzionare il backport su https://github.com/testing-cabal/mock mentre questo non fa parte dei suoi moduli incorporati. –

2

Dal python 3.4 è possibile utilizzare unittest.TestCase metodo di classe assertLogs

import logging 
import unittest 


class LoggingTestCase(unittest.TestCase): 
    def test_logging(self): 
     with self.assertLogs(level='INFO') as log: 
      logging.info('Log message') 
      self.assertEqual(len(log.output), 1) 
      self.assertEqual(len(log.records), 1) 
      self.assertIn('Log message', log.output[0]) 
+0

Grazie, questo è il modo migliore per affrontare i casi di test che coinvolgono logger. – Abhijeet

Problemi correlati