尝试在执行map_async()
操作的函数周围编写一些单元测试。更具体地说,我想确认一些文件在其中一个进程发生异常时被清除。下面提供了有意图的伪代码示例。
foo.py
def write_chunk(chunk):
... create file from chunk
return created_filename
class Foo:
def write_parallel(chunks):
filenames = set()
try:
pool = Pool(processes=2)
pool.map_async(write_chunk, chunks, callback=filenames.add)
except Exception:
//handle exception
finally:
cleanup_files(filenames)
test_foo.py
@patch("foo.write_chunk")
def test_write_parallel_exception_cleanup(self, mock_write_chunk):
def mock_side_effect(chunk):
if "chunk_1" == chunk:
raise Exception
else:
return chunk
mock_write_chunk.side_effect = mock_side_effect
foo = Foo()
foo.write_parallel({"chunk_1", "chunk_2"})
//assert "chunk_2" cleaned up and exception is thrown.
但是,当我去执行测试时,我得到以下PicklingError:PicklingError: Can't pickle <class 'mock.MagicMock'>: it's not the same object as mock.MagicMock
。
如何用我自己的模拟函数执行替换映射函数所需的结果?
答案 0 :(得分:1)
因为问题源于尝试Mock和Pickle这个函数,我决定将功能拉出到一个单独的函数,模拟该函数,同时允许原始函数被pickle。见下文:
foo.py
def write_chunk(chunk):
return write_chunk_wrapped(chunk)
def write_chunk_wrapped(chunk)
... create file from chunk
return created_filename
class Foo:
def write_parallel(chunks):
filenames = set()
try:
pool = Pool(processes=2)
pool.map_async(write_chunk, chunks, callback=filenames.add)
except Exception:
//handle exception
finally:
cleanup_files(filenames)
test_foo.py
@patch("foo.write_chunk_wrapped")
def test_write_parallel_exception_cleanup(self, mock_write_chunk_wrapped):
def mock_side_effect(chunk):
if "chunk_1" == chunk:
raise Exception
else:
return chunk
mock_write_chunk_wrapped.side_effect = mock_side_effect
foo = Foo()
foo.write_parallel({"chunk_1", "chunk_2"})
//assert "chunk_2" cleaned up and exception is thrown.