2013-10-30 11 views
6

Sto testando un'API personalizzata in python che effettua richieste http, ma non voglio fare una richiesta al sistema esterno reale ogni volta che corro i test unitari. Sto usando la libreria fittizia di Python con una funzione side_effect per simulare dinamicamente la risposta dell'API. Come faccio a far sì che il metodo side_effect si comporti come un metodo di classe?Come usare python Mock side_effect per agire come un metodo di classe in unit test

import requests 

class MyApiClass(): 
    def make_request(self, params): 
     return requests.get('http://someurl.com', params=params) 

    def create_an_object(self, params): 
     return self.make_request(params) 

import unittest, mock 

def side_effect_func(self, params): 
    if params['name'] == 'Specific Name': 
     return {'text': 'Specific Action'} 
    else: 
     return {'text': 'General Action'} 

class MyApiTest(unittest.TestCase): 
    def setUp(self): 
     super(MyApiTest, self).setUp() 
     mocked_method = mock.Mock(side_effect=side_effect_func) 
     MyApiClass.make_request = mocked_method 

    def test_create_object(self): 
     api = MyApiClass() 
     params = {'name': 'Specific Name'} 
     r = api.create_an_object(params) # Complains that two arguments are needed! 
     self.assertEqual(r['text'], 'Specific Action') 

ottengo questo errore

TypeError: side_effect_func() takes exactly 2 arguments (1 given) 

ma voglio side_effect_func passare api come primo argomento. Apprezzo qualsiasi aiuto!

risposta

4

Il modo più semplice sarebbe probabilmente quello di trasformare il tuo metodo di simulazione in un singolo argomento, quindi fare riferimento a MyApiClass staticamente all'interno del metodo di simulazione stesso. Altrimenti, si potrebbe provare a deridere l'oggetto classe stesso (fondamentalmente facendo una simulazione metaclasse) o magari usando una fabbrica che utilizza partial per creare al volo un metodo di simulazione di classe. Ma se il singolo argomento/metodo di riferimento statico funzionasse per te, mi sembra il migliore.

Inoltre, dai documenti Mock, c'è mocking an unbound method using patch, che sembra che potrebbe essere più quello che ti serve.

+1

Sì, grazie! Penso che deridere un metodo non associato con patch sia ciò di cui ho bisogno. In caso contrario, il tuo suggerimento di hardcoding su MyApiClass dovrebbe funzionare. – conman

Problemi correlati