模拟 url 进行单元测试

mocking of url for unittesting

我想模拟 urllib.urlopen 以创建单元测试

def url_test(self):
  response = urllib2.urlopen(test_url)
  body = response.read()
  if body:
    return body.split(':')[0]

config.py

 test_url = "localhost"

我想模拟 url_test() 函数,但我不明白如何模拟 test_url 的值。因为当我尝试对函数进行单元测试时,它说我 "connection refused"

这是我试过的。

@patch('urllib.urlopen')
def url_test(self, m_url):
  m_response = m_url.return_value
  m_response.read.return_value = 'Some body value:you wanted to return'
  self.assertTrue(url_test(), "Failed")
  m_url.assert_called_with('localhost')

您可以模拟 任何外部系统,这里是 urllib2。假设您使用的是 unittest.mock library (backported to Python 2 as the mock project):

with mock.patch('urllib2.urlopen') as urlopen_mock:
    mock_response = urlopen_mock.return_value
    mock_response.read.return_value = 'Some body value:you wanted to return'

    # call the method being tested
    result = someobject.url_test()

    # make assertion about the return value and that the code tried to use 
    # a specific URL
    urlopen_mock.assert_called_with('localhost')
    self.assertEqual(result, 'Some body value')

在您的更新中,您模拟了错误的位置:

@patch('urllib.urlopen')

您的代码使用 urllib2,而不是 urllib

对于 Python 中的模拟网络请求,我强烈推荐 HTTPretty

您想要执行的操作的一个简单示例如下所示:

@httpretty.activate
def test_url():
    httpretty.register_uri(httpretty.GET, test_url,
                           body='some body value:some other value',
                           content_type="text/plain")

    self.assertEqual(url_test(), 'some_body_value')

模拟 URL 请求会带来很多复杂的事情和陷阱,而 HTTPretty 很好地让它们在幕后发生。

就您的功能而言,考虑使 test_url 成为方法的参数而不是全局变量 - 这会大大简化测试。