2017-03-26 26 views
1

在python中使用mockito进行单元测试时,遇到了一个我找不到解决方案的问题。我正试图在给定的类方法中修补io.BytesIO的用法。下面的代码显示了出现问题的一个简化版本:如何使用mockito在python中修补内置/扩展类型?

from mockito import mock, patch, when 
from io import BytesIO 

class Foo: 
    def bar(self): 
     buffer = io.BytesIO() 
     # ... 
     return buffer.getvalue() 

def test_foo(): 
    bytesIO_mock = mock(strict=True) 
    when(bytesIO_mock).getvalue().thenReturn('data') 

    patch(BytesIO.__new__, lambda: bytesIO_mock) 
    result = Foo().bar() 
    assert result == 'data' 

我收到以下错误,当我执行测试:

/venv/lib/python3.6/site-packages/mockito/mockito.py:270: in patch 
when2(fn, Ellipsis).thenAnswer(replacement) 
/venv/lib/python3.6/site-packages/mockito/mockito.py:245: in when2 
return invocation.StubbedInvocation(theMock, name)(*args, **kwargs) 
/venv/lib/python3.6/site-packages/mockito/invocation.py:284: in __call__ 
self.mock.stub(self.method_name) 
/venv/lib/python3.6/site-packages/mockito/mocking.py:117: in stub 
self.replace_method(method_name, original_method) 
/venv/lib/python3.6/site-packages/mockito/mocking.py:108: in replace_method 
self.set_method(method_name, new_mocked_method) 

self = <mockito.mocking.Mock object at 0x10d50cb38>, method_name = '__new__' 
new_method = <function Mock.replace_method.<locals>.new_mocked_method at 0x10d753e18> 

    def set_method(self, method_name, new_method): 
>  setattr(self.mocked_obj, method_name, new_method) 
E  TypeError: can't set attributes of built-in/extension type '_io.BytesIO' 

/venv/lib/python3.6/site-packages/mockito/mocking.py:74: TypeError 

有没有解决这个问题,还是只是这是不可能嘲笑python中的某些对象?

回答

1

而不是使用patch你可以简单地嘲笑从io.BytesIO()响应如下:

def test_foo(): 
    bytesIO_mock = mock(strict=True) 

    when(bytesIO_mock).getvalue().thenReturn('data') 
    when(io).BytesIO().thenReturn(bytesIO_mock) 

    result = Foo().bar() 
    assert result == 'data' 

作为一个经验法则,所有的Python对象都可以嘲笑as everything in Python is an object。如果你不能嘲笑它,这可能是由于正在使用的测试库/框架的限制。