2017-06-13 1 views
0

Seit vergangenen Tagen habe ich versucht, einen einfachen Test zu schreiben, der überprüft, ob meine App funktioniert. Ich wurde direkt nach der Fertigstellung meines Programms mit Tests vertraut gemacht, deshalb schreibe ich danach Tests.Django Tests, instagram spotting Fehler

Ich verwende Python-instagram-ext als Bibliothek und Python-Version 3.5.2

Das eigentliche Programm korrekt funktioniert. Es ruft einfach die Daten von Instagram ab, speichert einige davon in Variablen und druckt sie aus.

def handle_instagram(self, max_tag_id, search_string=settings.SEARCH_STRING, return_count=1): 
    instagram_api = InstagramAPI(access_token=access_token, client_secret=client_secret) 
    search_string = search_string.replace('#', '') 
    recent_media, next_ = instagram_api.tag_recent_media(count=5, max_tag_id=None,tag_name=search_string) 

    id = recent_media[0].id 
    print(id) 

Und dieser Teil funktioniert sehr gut. Aber ich möchte nicht, dass mein Test Daten von Instagram API anfordert, also verwende ich Mock, um diese Funktion zu verspotten.

from django.test import TestCase 
from palautebot.models import Feedback 
from django.core.management.base import BaseCommand 
from palautebot.management.commands.palautebot import Command 
import instagram 
import datetime 

class TestPalautebotTests(TestCase): 
    palautebot_cmd = Command() 
@mock.patch('palautebot.management.commands.palautebot.InstagramAPI') 
    def test_handle_instagram(self, palautebot_instagram): 
     instagram_api = palautebot_instagram.InstagramAPI.return_value 
     user = instagram.models.User(1234, full_name='Test Account', username='test', profile_picture='http://pic.jpg') 
     recent_media = [instagram.models.Media(
      users_in_photo= [], 
      comment_count= 0, 
      link= 'https://www.google.fi', 
      filter= 'Crema', 
      caption= instagram.models.Comment(created_at=datetime.datetime(2017, 6, 12, 9, 5, 10), user=user, id='1234', text='#nofilter Instagram test'), 
      like_count= 0, 
      id= '0000000000000000001_0000000001', 
      comments= [], 
      images= { 
       'thumbnail': instagram.models.Image('http://www.google.fi', 50, 50), 
       'low_resolution': instagram.models.Image('http://www.google.fi', 150, 150), 
       'standard_resolution': instagram.models.Image('http://www.google.fi', 400, 400) 
      }, 
      tags= [instagram.models.Tag('nofilter')], 
      likes= [], 
      user= user, 
      type= 'image', 
      user_has_liked= False, 
      created_time= datetime.datetime(2017, 6, 12, 9, 5, 10))] 

     next_ = None 
     instagram_response = (recent_media, next_) 
     instagram_api.tag_recent_media.return_value = instagram_response 
     success_list= self.palautebot_cmd.handle_instagram(None, search_string='#nofilter') 
     self.assertEqual(success_list, [True]) 

Ich habe ähnlichen Mock mit Facebook api und das funktioniert gut, aber wenn ich versuche, diese Mock mit instagram zu tun, wirft er einen Fehler:

Traceback (most recent call last): 
    File "/usr/local/lib/python3.5/dist-packages/mock/mock.py", line 1305, in patched 
    return func(*args, **keywargs) 
    File "/home/bew/bew/src/palautebot/palautebot/tests.py", line 80, in test_handle_instagram 
    success_list= self.palautebot_cmd.handle_instagram(None, search_string='#helpalaute') 
    File "/home/bew/bew/src/palautebot/palautebot/management/commands/palautebot.py", line 162, in handle_instagram 
    tag_name=search_string 
ValueError: not enough values to unpack (expected 2, got 0) 

Zuerst war ich zuversichtlich, dass das Problem mit der war Daten, die ich als return_value verwende. Aber es ist egal, ob ich etwas davon wegnehme oder versuche, es mit Pickle in Variable zu speichern. Im obigen Beispiel erzeuge ich die Daten manuell mit der Instagram-Bibliothek. Die Daten sind ähnlich mit den Daten, die ich von Instagram bekomme.

edit: Es stellte sich heraus, dass es etwas sehr seltsam in der Python-instagram-ext Bibliothek geht oder in der instagram api, weil max_tag_id mit meiner ID nicht funktioniert. Es scheint also das Problem nicht mit dem Test, sondern mit api zu sein.

+0

Try @ mock.patch ( .InstagramAPI ') – vZ10

+0

Diese App hat keine Aussicht – Dosentti

+0

Ok. Pfad zur Handler_intagram-Methode – vZ10

Antwort

0

Ich konnte das Problem nicht auf die gleiche Weise lösen wie früher, aber ich fand einen Weg, um es zu umgehen. Anstatt also instagramAPI zu verspotten, spotze ich bestimmte Funktionen mit den Einstellungen side_effect für den Schein.

class TestPalautebotTests(TestCase): 
     def mock_initialize_instagram(): 
      instagram_api = instagram.client.InstagramAPI(
       access_token='access_token_foo', 
       client_secret='client_secret_bar' 
      ) 
      return instagram_api 

     def mock_tag_recent_media(count=60, max_tag=None, tag_name=''): 
      recent_media_mock = 'instagram-data' 
      next_ = None 
      mock_data_from_instagram = (recent_media, next_) 
      return mock_data_from_instagram 

     @mock.patch('palautebot.management.commands.palautebot.Command.initialize_instagram',side_effect=mock_initialize_instagram) 
     @mock.patch('palautebot.management.commands.palautebot.InstagramAPI.tag_recent_media',side_effect=mock_tag_recent_media) 
     @mock.patch('palautebot.management.commands.palautebot.Command.answer_to_instagram',side_effect=return_true) 
     def test_handle_instagram(
      self, 
      mock_init_instagram, 
      mock_tag_recent_media, 
      mock_answer_to_instagram 
     ): 
      self.assertEqual(self.palautebot_cmd.handle_instagram(None), [True])