简体   繁体   中英

Random not working with mock in nosetest

Im practising with unit testing and nose tests from a simple game and I have a section of the game that has dice rolls with random.randint which I need to test. I have been following this article on how to test random events with mock

http://www.jjinux.com/2014/01/python-lightning-quick-introduction-to.html

Im getting this error when I run nosetests though

ERROR: tests.ex47_tests.test_dice_roll
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1297, in patched
    arg = patching.__enter__()
  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1353, in __enter__
    self.target = self.getter()
  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1520, in <lambda>
    getter = lambda: _importer(target)
  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1210, in _importer
    thing = _dot_lookup(thing, comp, import_path)
  File "/usr/local/lib/python2.7/site-packages/mock/mock.py", line 1199, in _dot_lookup
    __import__(import_path)
ImportError: No module named random

I have imported random so not sure why that isn't working or is this something to do with mock?

Here is the portion of code from the game file and tests file (Ive not put all code here as I dont think needed)

game.py

class Intro(Rooms):

def enter(self):
    print "Intro room"

    print "You see the Gothon, you have to fight him!"

def dice_roll_fight(self):
    print 'DICE ROLL'

    dice_roll = randint(1,6)
    print "You rolled a ", dice_roll
    if dice_roll <= 2:
        return 'death'

    elif dice_roll >= 3:
        return 'starter'

    else:

        print "ERROR try again"

ex47_tests.py

from nose.tools import *
from ex47.game import Intro
from mock import mock
import random


@mock.patch('ex47.game.random.randint')
def test_dice_roll(randint_mock):
randint_mock.return_value = 1
assert_equal(game.dice_roll_fight(), 'death')


@mock.patch('ex47.game.random.randint')
def test_dice_roll(randint_mock):
randint_mock.return_value = 2
assert_equal(game.dice_roll_fight(), 'death')

@mock.patch('ex47.game.random.randint')
def test_dice_roll(randint_mock):
randint_mock.return_value = 3
assert_equal(game.dice_roll_fight(), 'starter')

Based on how are calling rand_int in your Intro class, you are probably importing this way:

from random import randint

In that case, your patching should be as such:

@mock.patch('ex47.game.randint')

The way you are patching:

@mock.patch('ex47.game.random.randint')

Indicates that you are importing like this:

import random

Furthermore, I see a few of problems in your test code.

  1. You are importing random in your tests. You should not need to do this. You are patching correctly (patching with respect to what you are testing), so you do not need to import random since you will be properly patching your random method with respect to your game module.

  2. It seems like you are trying to call your methods without actually instantiating your class. If you haven't already, you should set up your test as:

    class ThisIsMyTest(unittest.TestCase): def setUp(self): self.game = Intro()

  3. Your test methods are all named the same. This will end up only running one test and you will not be receiving the other results you want to test.

With the above three mentions in mind, the following code should suffice to help with your unit testing:

import unittest
from nose.tools import assert_equal
from game import Intro
from mock import mock


class GameTest(unittest.TestCase):

    def setUp(self):
        self.game = Intro()

    @mock.patch('game.randint')
    def test_dice_roll_one(self, randint_mock):
        randint_mock.return_value = 1
        from nose.tools import assert_equal
        assert_equal(self.game.dice_roll_fight(), 'death')

    @mock.patch('game.randint')
    def test_dice_roll_two(self, randint_mock):
        randint_mock.return_value = 2
        assert_equal(self.game.dice_roll_fight(), 'death')

    @mock.patch('game.randint')
    def test_dice_roll_three(self, randint_mock):
        randint_mock.return_value = 3
        assert_equal(self.game.dice_roll_fight(), 'starter')


if __name__ == '__main__':
    unittest.main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM