2016-04-14 10 views
5

Próbuję wyśmiać jedną konkretną funkcję boto3. Mój moduł, Sprzątanie, importuje boto3. Oczyszczanie ma również klasę "czystszą". Podczas init odkurzacz tworzy klienta EC2:Jak wyśmiać obiekt klienta Boto3/zadzwonić pod numer

self.ec2_client = boto3.client('ec2') 

Chcę mock metodę klienta EC2: desribe_tags(), która mówi, że jest pyton:

<bound method EC2.describe_tags of <botocore.client.EC2 object at 0x7fd98660add0>> 

najdalej stałam jest importowanie botocore w moim pliku testowego i starając:

mock.patch(Cleaner.botocore.client.EC2.describe_tags) 

która nie z:

AttributeError: 'module' object has no attribute 'EC2' 

Jak mogę sfałszować tę metodę?

Cleanup wygląda następująco:

import boto3 
class cleaner(object): 
    def __init__(self): 
     self.ec2_client = boto3.client('ec2') 

Przedmiotem ec2_client jest ten, który ma desribe_tags() metoda. Jest to obiekt botocore.client.EC2, ale nigdy nie importuję bezpośrednio botocore.

+0

Wewnątrz modułu oczyszczania. Jak dokładnie importujesz EC2, aby go użyć? Z jego wyglądu robisz coś takiego jak "import boto3". Dobrze? Podejrzewam więc, że twoje łatanie powinno wyglądać jak "Cleanup.boto3.EC2". Jeśli nadałeś nazwę modułowi "Oczyszczanie". Niektóre dodatkowe informacje na pewno by pomogły. – idjaw

+0

Próbka modułu dodanego –

+0

@JeffTang znalazłeś rozwiązanie? Szukam czegoś podobnego! – ptimson

Odpowiedz

0

Należy kpić ze względu na miejsce testowania. Tak więc, jeśli testujesz swoją klasę cleaner (Co sugeruję, użyj tutaj standardów PEP8 i uczyń ją Cleaner), wtedy chcesz kpić ze względu na to, gdzie testujesz. Tak, Twój łatanie powinny być rzeczywiście coś wzdłuż linii:

class SomeTest(Unittest.TestCase): 
    @mock.patch('path.to.Cleaner.boto3.client', return_value=Mock()) 
    def setUp(self, boto_client_mock): 
     self.cleaner_client = boto_client_mock.return_value 

    def your_test(self): 
     # call the method you are looking to test here 

     # simple test to check that the method you are looking to mock was called 
     self.cleaner_client.desribe_tags.assert_called_with() 

sugeruję czytanie przez mocking documentation który ma wiele przykładów, aby robić to, co staramy się robić

+0

Nie próbuję wykpić 'boto3.client'. Próbuję kpić z metody 'describe_tags' obiektu' botocore.client.EC2', który jest zwracany przez 'boto3.client' –

+0

. Wciąż tworzysz klienta działającego w EC2, ale chcesz udawać metoda z tego obiektu, który tworzysz? Zazwyczaj podczas testowania jednostkowego i próbnego poprawiania, chcesz wyłudzić zewnętrzne, jak ten klient EC2. Nadal będziesz w stanie sprawdzić poprawność tej metody, którą chcesz przetestować za pomocą wartości zwracanej 'boto_client_mock'. – idjaw

+0

@JeffTang Podałem bardziej szczegółowy przykład (nietestowany, po prostu chciałem przedstawić ogólny pomysł) tego, czego możesz chcieć * robić. – idjaw

1

znalazłem rozwiązanie tego kiedy trying to mock a different method for the S3 client

import botocore 
from mock import patch 
import boto3 

orig = botocore.client.BaseClient._make_api_call 

def mock_make_api_call(self, operation_name, kwarg): 
    if operation_name == 'DescribeTags': 
     # Your Operation here! 
     print(kwarg) 
    return orig(self, operation_name, kwarg) 

with patch('botocore.client.BaseClient._make_api_call', new=mock_make_api_call): 
    client = boto3.client('ec2') 
    # Calling describe tags will perform your mocked operation e.g. print args 
    e = client.describe_tags() 

Nadzieja to pomaga :)