【问题标题】:How to patch OS.mkdir with Mock?如何使用 Mock 修补 OS.mkdir?
【发布时间】:2014-09-02 12:31:51
【问题描述】:

我正在尝试使用带有 pytest 的 Mock 模块进行单元测试。

我希望 os.path.isdir() 返回 False,并且 os.mkdir() 不运行;我只是想验证传递给它的参数是否正确。

我想你只需要看set_path方法

我的应用:

import pytumblr, os, sys, prowlpy, json, collections
from urllib2 import urlopen
from time import sleep
from apiclient.discovery import build

class Site(object):
    """A generic site."""
    def __init__(self, user):
        self.user = user

    def set_path(self):
        if os.path.isdir(self.user_dir):            # if user dir already exists
            print "**Directory already exists: ", self.user_dir
        else:
            os.mkdir(self.user_dir)                 # else create user dir
            print "Created Directory: ", self.user_dir

class Tumblr(Site):
    """A tumblr blog."""
    type = "tumblr"
    type_dir = os.path.join(os.getcwd(), type)
    def __init__(self, user):
        super(Tumblr, self).__init__(user)
        self.user_dir = os.path.join(Tumblr.type_dir, self.user)

我的测试总是失败,如下所示:

import tumblrip_new as tum
import mock

    @mock.patch('tumblrip_new.os')
    @mock.patch('tumblrip_new.os.path')
    def test_create_new_user_dir(self, mock_path, mock_os):
        """Creates a directory if one does not exist."""
        t = tum.Tumblr("username")
        # directory does not exist:
        mock_path.isdir.return_value = False
        t.set_path()
        mock_os.mkdir.assert_called_with(t.user_dir)

输出显示失败的原因:

_mock_self = <MagicMock name='os.mkdir' id='33647664'>
args = (<MagicMock name='os.path.join()' id='33568048'>,), kwargs = {}
self = <MagicMock name='os.mkdir' id='33647664'>
expected = "mkdir(<MagicMock name='os.path.join()' id='33568048'>)"

>   ???
E   AssertionError: Expected call: mkdir(<MagicMock name='os.path.join()' id='3
568048'>)
E   Not called

build\bdist.win32\egg\mock.py:831: AssertionError
===================== 1 failed, 3 passed in 0.22 seconds ======================

【问题讨论】:

    标签: python unit-testing python-2.7 mocking


    【解决方案1】:

    我通过以下方式修复它:

    @mock.patch('tumblrip_new.os.path')
    @mock.patch('tumblrip_new.os')
    def test_create_new_user_dir(self, mock_os, mock_path):
        """Creates a directory if one does not exist."""
        t = tum.Tumblr("username")
        # directory does not exist:
        mock_path.isdir.return_value=False
        t.set_path()
        mock_os.mkdir.assert_called_with(t.user_dir)
    

    【讨论】:

      【解决方案2】:

      使用副作用更新模拟行为(os.path.isdir):

      import os
      import unittest
      from mock import Mock, MagicMock, patch
      from contextlib import nested
      
      """Creates a directory if one does not exist."""
      
      
      class Site(object):
          """A generic site."""
          def __init__(self, user):
              self.user = user
      
          def set_path(self):
              if os.path.isdir(self.user_dir):            # if user dir already exists
                  print "**Directory already exists: ", self.user_dir
              else:
                  os.mkdir(self.user_dir)                 # else create user dir
                  print "Created Directory: ", self.user_dir
      
      
      class Tumblr(Site):
          """A tumblr blog."""
          type = "tumblr"
          type_dir = os.path.join(os.getcwd(), type)
      
          def __init__(self, user):
              super(Tumblr, self).__init__(user)
              self.user_dir = os.path.join(Tumblr.type_dir, self.user)
      
      
      class testCreateDir(unittest.TestCase):
      
          def test_create_new_user_dir(self):
      
              os = MagicMock()
              os.path = MagicMock()
      
              os.path.isdir = Mock(return_value=False)
              os.path.join = Mock(return_value="user_dir")
      
              mkdir = Mock()
      
              def update_status(*args):
                  mkdir(args[0])
                  os.path.isdir.return_value = True
      
              os.mkdir = Mock(side_effect=update_status)
      
              with nested(patch('os.path', os.path), patch('os.mkdir', os.mkdir)):
                  t = Tumblr("username")
                  t.set_path()
                  mkdir.assert_called_with(t.user_dir)
                  t.set_path()
                  t.set_path()
                  t.set_path()
                  mkdir.assert_called_once_with(t.user_dir)
      

      【讨论】:

        猜你喜欢
        • 2012-06-24
        • 2012-04-24
        • 1970-01-01
        • 2011-07-17
        • 1970-01-01
        • 1970-01-01
        • 2012-09-19
        • 2013-08-15
        • 2012-09-01
        相关资源
        最近更新 更多