title: How to mock socket module in python?
body: <p>I am working on a multicast project with <code>python3</code> and have a small program to search for <code>upnp</code> devices on the local network. I want to use <code>unittest</code> and <code>mock</code> the expensive call to <code>socket.recvfrom(bufsize[, flags])</code>.</p>
  
  <p>Here is my program <code>./upnp/mucassdp.py</code>:</p>
  
  <pre><code>#!/usr/bin/env python3
  
  import socket
  
  class ssdpObj():
  # Handle Simple Service Discovery Protocol,
  # for discovering UPnP devices on the local network
  
      def msearch(self):
          msg = \
              'M-SEARCH * HTTP/1.1\r\n' \
              'HOST:239.255.255.250:1900\r\n' \
              'ST:upnp:rootdevice\r\n' \
              'MX:2\r\n' \
              'MAN:"ssdp:discover"\r\n' \
              '\r\n'
  
          # Set up UDP socket with timeout and send a M-SEARCH structure
          # to the upnp multicast address and port
          s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
          s.settimeout(2)
          s.sendto(msg.encode(), ('239.255.255.250', 1900) )
  
          # print received data within the timeout
          try:
              while True:
                  # expensive call to mock for testing
                  data, addr = s.recvfrom(65507)
  
                  print (addr, data.decode(), end='')
          except socket.timeout:
              pass
  </code></pre>
  
  <p>And here is my test case <code>./tests/mucassdpTest.py</code>:</p>
  
  <pre><code>#!/usr/bin/env python3
  
  import unittest
  from unittest.mock import patch
  
  from upnp.mucassdp import ssdpObj
  
  
  class mucassdpTestCase(unittest.TestCase):
  
      @patch('upnp.mucassdp.socket')
      def test_msearch(self, mock_socket):
          # instantiate our service
          oSsdp = ssdpObj()
  
          mock_socket.recvfrom.return_value = [0, '1']
          #mock_socket.recvfrom.side_effect = [0, '1']
  
          oSsdp.msearch()
          mock_socket.settimeout.assert_called_with(2)
  </code></pre>
  
  <p>When I try to run the test case with:</p>
  
  <pre><code>~$ python3 -m unittest tests.mucassdpTest
  </code></pre>
  
  <p>I get the error message (only relevant part):</p>
  
  <pre><code>ERROR: test_msearch (tests.mucassdpTest.mucassdpTestCase)
  ----------------------------------------------------------------------
  Traceback (most recent call last):
    File "/home/ingo/devel/muca-tools/upnp/mucassdp.py", line 27, in msearch
      data, addr = s.recvfrom(65507)
  ValueError: not enough values to unpack (expected 2, got 0)
  </code></pre>
  
  <p>I've looked around and found some similar questions and answers, e.g. initialize <code>Mock</code> through its constructor with the expected <code>data, addr</code> or setup <code>side_effect</code> ( I've tried this) but I cannot get it to run successfully with my test.</p>
  
  <p>How do I have to set up the patched <code>socket</code> module to get the expected paired <code>data, addr</code> from <code>s.recvfrom(...)</code> under test conditions?</p>