Pour rappel, je suis resté un peu bloqué lorsque j'ai écrit le test en convertissant urllib2.urlopen () en Mock.
En fait, c'est beaucoup de code, mais par souci de simplicité, cela ressemble à ce qui suit.
target.py
import urllib2
def get(url):
return urllib2.urlopen().read()
C'est le premier code que j'ai écrit facilement. Il ne semble y avoir aucun problème avec un cas, mais si vous exécutez ceci, ** la première assertion passera, mais avec la deuxième assertion, AssertionError: 'hoge'! = '' Se produira et une erreur ** se produira.
bad_test_sample.py
from nose.tools import *
from mock import Mock
from StringIO import StringIO
import urllib2
import target
def test_get():
urllib2.urlopen = Mock(return_value=StringIO('hoge'))
eq_('hoge', target.get("http://dummy-url"))
eq_('hoge', target.get("http://dummy-url"))
Si c'est la première fois, une erreur se produira après la deuxième fois. ?? ?? Ce sera. Le test réel ne serait pas exécuté deux fois comme ça, il ressemble donc à une erreur à un moment apparemment étrange. Au moins c'était mon temps.
En conclusion, ** "Read is required-> Create with StringIO" est faux **, alors ne faites pas cela et utilisez simplement Mock.
good_test_sample.py
from nose.tools import *
from mock import Mock
import urllib2
import target
def test_get():
urllib2.urlopen = Mock()
urllib2.urlopen.return_value.read.return_value = 'hoge'
eq_('hoge', target.get("http://dummy-url"))
eq_('hoge', target.get("http://dummy-url"))
Si vous le passez avec StringIO, il viendra certainement avec une méthode read () appropriée, mais au contraire, parce que c'est correct, ** le même flux sera référencé dans la deuxième exécution et les suivantes, et le pointeur est déjà à la fin * *. Donc, après la deuxième fois, read () ne donne rien. Après tout, la zone autour du pointeur est obligatoire pour un programmeur.