Luc*_*cia 6 python unit-testing mocking python-unittest
我试图os.environ在课堂上进行模拟,但我就是做对了。这是我的结构:
#file.py
import os
class MyClass():
connection_url = os.environ['DB']
#some code
Run Code Online (Sandbox Code Playgroud)
这是我的测试(无论如何都是最新的尝试):
#test.py
from unittest import TestCase
from unittest.mock import patch
from file import MyClass
class TestMyClass(TestCase):
@patch.dict('file.os.environ', {'DB' : 'Dummy' })
def setUp(self):
self.class = MyClass()
#some testing
Run Code Online (Sandbox Code Playgroud)
这是悲惨地失败,引发 KeyError 'DB' ... 有人可以帮助我吗?我是 python 单元测试的新手。我研究了一些博客和 stackoverflow,尝试了一些解决方案,但无法解决问题。
提前致谢!
这里的问题是connection_url在创建类时(在导入时)设置的。如果你想模拟它,你可以在使用该属性之前修补类本身的属性:
class TestMyClass(TestCase):
@patch.object(file.MyClass, 'connection_url', 'Dummy')
def setUp(self):
self.instance = MyClass()
Run Code Online (Sandbox Code Playgroud)
您仍然需要处理KeyError导入时的潜在问题 - 即,您需要确保您的测试运行程序在导入文件之前在环境中具有虚拟值,否则您必须将代码修改file.py为确保它不会引发KeyError. 这里有一些策略。如果未在环境中设置,您可以直接禁止KeyError出租:connection_url = default_value
class MyClass():
connection_url = os.environ.get('DB', default_value)
Run Code Online (Sandbox Code Playgroud)
或者您可以将 connection_url 提取移至__init__:
class MyClass():
def __init__(self):
connection_url = os.environ['DB']
Run Code Online (Sandbox Code Playgroud)
后一个代码还有一个额外的好处,您patch.dict应该开始工作。
请注意,如果您选择前两种方法中的任何一种,则实例将仅connection_url在该setUp方法期间进行修补 - 后续测试将不会进行修补。这很可能会成为一个阻碍,您需要在每个测试中创建一个新实例:
class TestMyClass(TestCase):
@patch.object(file.MyClass, 'connection_url', 'Dummy')
def test_first_thing(self):
self.instance = MyClass()
...
@patch.object(file.MyClass, 'connection_url', 'Dummy')
def test_second_thing(self):
self.instance = MyClass()
...
Run Code Online (Sandbox Code Playgroud)