python - Mock an entire package with pytest and pytest-mock -


i have class uses package tmdbsimple:

movie.py

import tmdbsimple tmdb  tmdb.api_key = '12345'  class movie():     def __init__(self, tmdb_id):         movie = tmdb.movies(tmdb_id)         response = movie.info()          self.tmdb_id = tmdb_id         self.title = movie.title         self.vote_average = movie.vote_average         self.watched = false *snip* 

this , until want test without relying on actual connection tmdb:

test_movie.py

import pytest  import movie fake_tmdbsimple import faketmdbsimple  @pytest.fixture def testmovie(mocker):     mocker.patch.dict('sys.modules', {'tmdbsimple': faketmdbsimple()})     return movie.movie('1')  def test_creation_of_movie(testmovie):     assert isinstance(testmovie, movie.movie)  def test_properties_of_movie(testmovie):     assert testmovie.tmdb_id == 1     assert testmovie.title == 'example movie'     assert testmovie.vote_average == 10     assert testmovie.watched == false 

fake_tmdbsimple.py

class faketmdbsimple():     def __init__(self):         pass      class movies():         _example_movie_data = {             1: {                 'title': 'example movie',                 'vote_average': 10.0             }         }          def __init__(self, tmdb_id):             self.tmdb_id = tmdb_id          def info(self):             self.title = self._example_movie_data[self.tmdb_id]['title']             self.vote_average = self._example_movie_data[self.tmdb_id]['vote_average']      class find():         def __init__(self, identifier):             pass          def info(self, external_source):             return {                 'movie_results': [                     {'id': 1}                 ]             }      class search():         def __init__(self):             pass          def movie(self, query):             return {                 'results': [                     {                         'id': 1                     }                 ]             } 

when test runs, error:

*snip* self = <tmdbsimple.movies.movies object @ 0x110779cf8>      def __init__(self): >       . import api_version e       importerror: cannot import name 'api_version' 

the test still trying import real tmdbsimple! testmovie object still receives instance of tmdbsimple.movies.movies instead of fake_tmdbsimple.movies when calling tmdb.movies(). relatively sure result of "not mocking object used, coming from." however, in case, using pytest , pytest-mock, not know how make mock happen needs to.

am going right way? if so, need mock entire tmdbsimple package? if not, correct way test movie() class without accessing tmdb?

i had working implementation of before, so:

test_movie.py:

import pytest  pycoin import movie  @pytest.fixture def testmovie(fake_tmdbsimple):     return movie.movie('1')  @pytest.fixture def fake_tmdbsimple(monkeypatch):     monkeypatch.setattr('tmdbsimple.movies', faketmdbsimplemovies)     monkeypatch.setattr('tmdbsimple.find', faketmdbsimplefind)     monkeypatch.setattr('tmdbsimple.search', faketmdbsimplesearch)  class faketmdbsimplemovies():     _example_movie_data = {         1: {             'title': 'example movie',             'vote_average': 10.0         }     }      def __init__(self, tmdb_id):         self.tmdb_id = tmdb_id      def info(self):         self.title = self._example_movie_data[self.tmdb_id]['title']         self.vote_average = self._example_movie_data[self.tmdb_id]['vote_average']  class faketmdbsimplefind():     def __init__(self, identifier):         pass      def info(self, external_source):         return {             'movie_results': [                 {'id': 1}             ]         }  class faketmdbsimplesearch():     def __init__(self):         pass      def movie(self, query):         return {             'results': [                 {                     'id': 1                 }             ]         }  def test_creation_of_movie(testmovie):     assert isinstance(testmovie, movie.movie)  def test_properties_of_movie(testmovie):     assert testmovie.tmdb_id == 1     assert testmovie.title == 'example movie'     assert testmovie.vote_average == 10     assert testmovie.watched == false 

this had advantage of not requiring pytest-mock (and advantage of working...), seemed inelegant patch each of movies, find, , search individually. require re-implementation of fake classes if wanted test other modules fake version of tmdbsimple. annoys completionist in me tried mock out entire package can't figure out how.


Comments

  1. Great Post with valuable information. I am glad that I have visited this site. Share more updates.
    Pytest Online Training
    Pytest Online Course
    Artificial Intelligence Online Course


    ReplyDelete
  2. Nice blog, very informative content.Thanks for sharing, waiting for the next update…
    What is data science?
    What are the uses of DataScience?

    ReplyDelete

Post a Comment

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -