2016-08-09 12 views
2

deal()関数で2回呼び出されているpickCard()関数の出力をスタブする方法はありますか?私は敗北と勝利の両方のケースをテストしたい。
たとえば、pickCard()が呼び出された最初のケ​​ースでは、値8card1が与えられ、第2の指定値10card2が与えられます。python、スタブランダム性同じ関数で2回

@ Mock.patchを使用しようとしましたが、これは1回の呼び出しでのみ機能します。

import random 

class Game: 
    def __init__(self): 
     self.cards = [1,2,3,4,5,6,7,8,9,10] 

    def deal(self): 
     card1 = self.pickCard() 
     self.removeCards(card1) 
     card2 = self.pickCard() 
     return card1 + card2 > 16 

    def pickCard(self): 
     return random.choice(self.cards) 

    def removeCards(self,card1): 
     return self.cards.remove(card1) 

テストファイルは次のとおりです:

import unittest 
from mock import MagicMock 
import mock 
from lib.game import Game 

class TestGame(unittest.TestCase): 
    def setUp(self): 
     self.game = Game() 

    def test_0(self):#passing 
     """Only cards from 1 to 10 exist""" 
     self.assertListEqual(self.game.cards, [1,2,3,4,5,6,7,8,9,10]) 

    #Here is where I am finding difficulty writing the test 
    def test_1(self): 
     """Player dealt winning card""" 
     with mock.patch('lib.game.Game.pickCard') as mock_pick: 
      mock_pick.side_effect = (8, 10) 
      g = Game() 
      g.pickCard() 
      g.pickCard() 
      self.assertTrue(self.game.deal()) 

EDIT

私はself.blackjack.pickCard = MagicMock(return_value=8)を使用していたが、再び私はそれを2回使用している場合、それは、戻り値ここ

を上書きするコードです

私は上記のコードでこのテストを実行しました。このスタックを取得します代わりに

Traceback (most recent call last): 
tests/game_test.py line 26 in test_1 
    self.assertTrue(self.game.deal()) 
lib/game.py line 8 in deal 
    card1 = self.pickCard() 
/usr/local/lib/python2.7/site-packages/mock/mock.py line 1062 in __call__ 
    return _mock_self._mock_call(*args, **kwargs) 
/usr/local/lib/python2.7/site-packages/mock/mock.py line 1121 in _mock_call 
    result = next(effect) 
/usr/local/lib/python2.7/site-packages/mock/mock.py line 109 in next 
    return _next(obj) 

を渡すのCEは、私がテストの別の場所で2 g.pickCard()を配置する必要がありますか?または、何とかself.game.deal()メソッドでこれにアクセスする必要がありますか?

答えて

1

mock.patchは、移動するための方法であるが、代わりにreturn_valueのあなたはside_effect=(8, 10)

with mock.patch('lib.game.Game.pickCard') as mock_pick: 
    mock_pick.side_effect = (8, 10) 
    g = Game() 
    print(g.pickCard()) 
    print(g.pickCard()) 

# 8 
# 10 

EDIT#1

ピックカードを指定する必要があります別のカードが選ばれていることをちょうどデモのためでした。 あなたのコードでは、両方のカードを選んでを発生させていない別の2枚のカードを選択するgame.dealを呼び出します。 MagicMockと

def test_1(self): 
    """Player dealt winning card""" 
    with mock.patch.object(self.game, 'pickCard') as mock_pick: 
     mock_pick.side_effect = (8, 10) 
     self.assertTrue(self.game.deal()) 

あなたのパスオブジェクトのプロパティpickCardやだ、それを設定します。あなたのゲームオブジェクトが既に(セットアップで作成された)が存在するので、また、あなたはあなたのtest_1にする必要があります、したがって、新しいゲームオブジェクトを作成しないで、直接、このオブジェクトにパッチを適用する必要があり副作用はそれぞれ8と10になりました。

+1

https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect – dm03514

+0

より洗練された方法が必要な場合は、各呼び出しで 'mock_pick'の動作を制御します、私の答えはこちらを参照してください:http://stackoverflow.com/questions/26783678/python-mock-builtin-open-in-a-class-using-two-different-files/38618056#38618056 – warownia1

+0

ありがとう@ warownia1、私は他のところで副作用を見ましたが、それを使う方法があまりにも分かりませんでした。私はまだスタブされたメソッドを使用することで問題を抱えています。上記のOPを参照してください。 – cani

関連する問題