模拟子进程进程终止

时间:2014-11-11 17:22:12

标签: python unit-testing

我无法找到与此完全相同的问题。我很难理解如何模拟subprocess.Popen的返回值,以便我可以在我尝试停止时调用terminate。 server.py类看起来像这样:

import os
import subprocess

class Server(object):

    def start(self):
        devnull = open(os.devnull, 'w')
        self.proc = subprocess.Popen(['python', '-c', 'import time; time.sleep(10);print "This message should not appear"'], stdout=devnull, stderr=devnull)

    def stop(self):
        if self.proc:
            self.proc.terminate()

我的测试类看起来像这样。我想知道在调用stop时调用terminate,但是当我用nose运行测试时,它表示终止被调用了0次。我对补丁的理解是它取代了subprocess.Popen的实现以及所有可用的方法。

from unittest import TestCase
from server import Server
from mock import patch, MagicMock, Mock

class ServerTest(TestCase):

    @patch("subprocess.Popen")
    @patch('__builtin__.open')
    def test_stop_when_running(self, mock_open, mock_subprocess):
        server = Server()
        server.start()
        server.stop()
        mock_subprocess.terminate.assert_called_once_with()

2 个答案:

答案 0 :(得分:1)

您需要模拟您正在测试的代码实际使用的Popen。所以补丁路径是:

@patch("server.subprocess.Popen")
@patch('server.__builtin__.open')
def test_stop_when_running(self, mock_open, mock_subprocess):
    server = Server()
    server.start()
    server.stop()
    mock_subprocess.terminate.assert_called_once_with()

但是,terminate的返回值会调用subprocess.Popen(),因此需要变为:

mock_subprocess.return_value.terminate.assert_called_once_with()

答案 1 :(得分:0)

试试这个:

server.proc.terminate.assert_called_once_with()