2017-04-12 29 views
0

我试图测试一个Python方法包含with语句。 with声明中的代码可以引发RuntimeError。我正在谈论的测试是否提高了RuntimeErrorTestCase - 异常不会引发与嘲笑__enter__

__enter____exit__方法很重(通常是打开和关闭SSH连接),我在测试时嘲笑它们。

这里是方法的简化定义欲测试:

# client.py 
class Client(): 
    def method_to_test(): 
     with self: 
      raise RuntimeError() 

为了清楚的目的,我省略__enter____exit__的定义,并除去所有在method_to_test其中未参与的代码当前的问题。

为了测试这个方法,我嘲笑__enter____exit__,并检查是否RuntimeError提高:

# tests.py 
from django.test import TestCase 
import mock 
from .client import Client 

class ClientTestCase(TestCase): 
    @mock.patch('mymodule.client.Client.__enter__') 
    @mock.patch('mymodule.client.Client.__exit__') 
    def test_method_raises_Runtime(self, mock_exit, mock_enter): 
     mock_enter.return_value = None 
     client = Client() 
     with self.assertRaises(RuntimeError): 
      client.method_to_test() 

此测试失败:AssertionError: RuntimeError not raised

如果我不嘲笑__enter__,该RuntimeError升高。为什么嘲笑__enter__会使这个测试失败?

+0

什么是'mymodule'?我不认为你嘲笑正确的事情。 – chepner

+0

@chepner mymodule是client.py和tests.py所在的模块。当使用pdb时,我清楚地看到'self .__ enter__'和'self .__ exit__'类型是MagicMock,这意味着我在正确的位置上打补丁。 – Dunatotatos

回答

0

在PEP343 https://www.python.org/dev/peps/pep-0343/

The exception is swallowed if exit() returns true 

视为self.__exit__是在Client.method_to_testMagicMock一个,self.__exit__返回MagicMock,评价为True。吞咽了RuntimeError

修复很简单。 self.__exit__()作为返回None代替MagicMock

# tests.py 
from django.test import TestCase 
import mock 
from .client import Client 

class ClientTestCase(TestCase): 
    @mock.patch('mymodule.client.Client.__enter__') 
    @mock.patch('mymodule.client.Client.__exit__') 
    def test_method_raises_Runtime(self, mock_exit, mock_enter): 
     # __exit__ returns None, evaluated as False 
     mock_exit.return_value = None 
     mock_enter.return_value = None 
     client = Client() 
     with self.assertRaises(RuntimeError): 
      client.method_to_test()