2017-03-15 6 views
1

私はPythonの初心者です。単体テストでパッチAPI呼び出しを模擬する方法を頭に入れて苦労しています。 FYI、私はPython 2.7を使用していて、nosetestを使用して単体テストのニーズを満たしています。ユニットテストでAPIを呼び出す

私はユニットテストしたい以下のモジュール(myRedis.py)があります限りユニットテストが行​​くよう

import logging 
import redis 

redispool = None 

class myRedis(object): 

def __init__(self, redisHost, redisPort, redisDBNum): 
    if not redisPort.isdigit(): 
     raise TypeError('Exception: Expected int for redisPort') 

    if not redisDBNum.isdigit(): 
     raise TypeError('Exception: Expected int for redisDBNum') 

    self._redis_instance = None 

    self._redishost = redisHost 
    self._redisport = redisPort 
    self._redisdb = redisDBNum 

    global redispool 
    redispool = redis.ConnectionPool(host=self._redishost, 
              port=self._redisport, 
              db=self._redisdb) 

    def redis_connect(self): 
     LOGGER.info('Connecting Redis client to %s:%s:%s', self._redishost, 
     self._redisport, self._redisdb) 
     self._redis_instance = redis.StrictRedis(connection_pool=redispool) 

    def write_redis(self, key, value): 
     retval = self._redis_instance.set(key, value) 
     LOGGER.info('Writing data to redis (%s, %s). Retval=%s', key, value, retval) 
     return retval 

    def read_redis(self, key): 
     retval = self._redis_instance.get(key) 
     LOGGER.info('Reading data from redis: key=%s. Retval=%s', key, retval) 
     return retval 

を、私は今のところ、次のしています。

from nose.tools import * 
import mock 
from myRedis import myRedis 

def setup(): 
    pass 
def teardown(): 
    pass 

@mock.patch('redis.StrictRedis') 
def test_mock_redis_StrictRedis(mock_conn_pool): 
    mock_conn_pool.return_value = True 
    assert(True) 

def test_myRedis(): 

    assert_raises(TypeError, myRedis, 
       'test', '1234', 'a11') 

    assert_raises(TypeError, myRedis, 
       'test', 'a1234', '11') 

    myRedisObj = myRedis('localhost', '8888', '11') 
    assert_equal(myRedisObj._redishost, 'localhost') 
    assert_equal(myRedisObj._redisport, '8888') 
    assert_equal(myRedisObj._redisdb, '11') 

    myRedisObj.redis_connect() 
    #oclRedis.read_redis('test') 
    #oclRedis.write_redis('test', 'test') 

redis.StrictRedis()呼び出しを問題なくパッチすることができます。しかし、私はredisのget()とset()呼び出しをオブジェクト(myRedis.pyの_redis_instance)で呼び出すので、どのようにパッチを適用しますか?私は@ mock.patch.objectのいくつかの異なるバージョンを試しましたが、それは私にとってはうまくいかなかったのです。いくつかのガイダンスを探しています。

ありがとうございます。

答えて

1

修正する必要があるのは、オブジェクトからの実際の呼び出しではなく、実際に呼び出されているオブジェクト自体です。あなたは私が一度に一つのことをテストするためにテストを修正

from nose.tools import * 
import mock 
import unittest 
from red import myRedis 

def setup(): 
    pass 
def teardown(): 
    pass 

@mock.patch('redis.StrictRedis') 
def test_mock_redis_StrictRedis(mock_conn_pool): 
    mock_conn_pool.return_value = True 
    assert(True) 

def test_myRedis_wrong_args(): 
    assert_raises(TypeError, myRedis, 
       'test', '1234', 'a11') 
    assert_raises(TypeError, myRedis, 
       'test', 'a1234', '11') 

def test_myRedis_ok(): 
    myRedisObj = myRedis('localhost', '8888', '11') 
    assert_equal(myRedisObj._redishost, 'localhost') 
    assert_equal(myRedisObj._redisport, '8888') 
    assert_equal(myRedisObj._redisdb, '11') 


@mock.patch('redis.StrictRedis.set') 
def test_myRedis_write(mock_strict_redis_set): 
    mock_strict_redis_set.return_value = {} 
    myRedisObj = myRedis('localhost', '8888', '11') 
    redis_connect = myRedisObj.redis_connect() 
    connect = myRedisObj.write_redis('1', '2') 
    assert connect == {} 

見ることができるように:あなたのコード、それはの線に沿って何かを考えて

。これは、副作用を回避し、テストの分離を保証するために一般的にしたいことです。

は、ドキュメントを見てみ考えてみましょう:https://docs.python.org/dev/library/unittest.mock.html

が最後にインデントはPythonで鍵となり、前方

を行くあなたのコードスニペットに適切なインデントを考えます
関連する問題