def test_two_stubs_same_service_as_decorator_multiple_calls_to_one( self, stub_test_action_1, stub_test_action_2): stub_test_action_1.return_value = {'value': 1} stub_test_action_2.side_effect = ({ 'another_value': 2 }, { 'third_value': 3 }) response = self.client.call_action('test_service', 'test_action_1') self.assertEqual({'value': 1}, response.body) response = self.client.call_action('test_service', 'test_action_2', {'input_attribute': True}) self.assertEqual({'another_value': 2}, response.body) response = self.client.call_action('test_service', 'test_action_2', {'another_attribute': False}) self.assertEqual({'third_value': 3}, response.body) self.assertEqual(1, stub_test_action_1.call_count) self.assertEqual({}, stub_test_action_1.call_body) self.assertEqual(2, stub_test_action_2.call_count) self.assertEqual({'another_attribute': False}, stub_test_action_2.call_body) self.assertEqual(({ 'input_attribute': True }, { 'another_attribute': False }), stub_test_action_2.call_bodies) stub_test_action_1.assert_called_once_with({}) stub_test_action_2.assert_has_calls([ mock.call({'input_attribute': True}), mock.call({'another_attribute': False}), ])
def test_send_unix_with_failure_part_way_through(self): with mock.patch.object(socket.socket, 'connect') as mock_connect: handler = SyslogHandler(address='/path/to/a/different.socket') mock_connect.assert_called_once_with('/path/to/a/different.socket') # This is weird. Creating a new socket actually dynamically creates the `send` method, which breaks mocking. # So we have to mock the send, connect, and close methods, and then when the send returns an error on the # second call, the close method has to de-mock send so that a new socket can be created, and then the # connection method has to re-mock send so that we can capture the send retries. Yuck. first_mock_send_patch = mock.patch.object(socket.socket, 'send') second_mock_send_patch = mock.patch.object(socket.socket, 'send') mock_sends = { 'first_mock_send': None, 'second_mock_send': None, } # type: Dict[six.text_type, Optional[mock.MagicMock]] def close_side_effect(*_, **__): first_mock_send_patch.stop() def connect_side_effect(*_, **__): m = second_mock_send_patch.start() m.side_effect = [True, True] mock_sends['second_mock_send'] = m try: with mock.patch.object(socket.socket, 'close') as mock_close, \ mock.patch.object(socket.socket, 'connect') as mock_reconnect: m = first_mock_send_patch.start() m.side_effect = [True, OSError()] mock_sends['first_mock_send'] = m mock_close.side_effect = close_side_effect mock_reconnect.side_effect = connect_side_effect handler._send([ 'this is the first part', 'here is another part', 'one more part' ]) finally: mock.patch.stopall() m = mock_sends['first_mock_send'] assert m is not None m.assert_has_calls([ mock.call('this is the first part'), mock.call('here is another part'), ]) m = mock_sends['second_mock_send'] assert m is not None m.assert_has_calls([ mock.call('here is another part'), mock.call('one more part'), ]) mock_reconnect.assert_called_once_with('/path/to/a/different.socket') mock_close.assert_called_once_with()
def test_send_udp(self): handler = SyslogHandler(address=('127.0.0.1', logging.handlers.SYSLOG_UDP_PORT)) with mock.patch.object(socket.socket, 'sendto') as mock_send_to: handler._send(['this is the first part', 'here is another part', 'one more part']) mock_send_to.assert_has_calls([ mock.call('this is the first part', ('127.0.0.1', logging.handlers.SYSLOG_UDP_PORT)), mock.call('here is another part', ('127.0.0.1', logging.handlers.SYSLOG_UDP_PORT)), mock.call('one more part', ('127.0.0.1', logging.handlers.SYSLOG_UDP_PORT)), ])
def test_send_receive_one_stub_multiple_calls(self, stub_test_action_1): stub_test_action_1.side_effect = ({'look': 'menu'}, {'pepperoni': 'pizza'}, {'cheese': 'pizza'}) request_id1 = self.client.send_request( 'test_service', [ {'action': 'test_action_1', 'body': {'menu': 'look'}}, {'action': 'test_action_1', 'body': {'pizza': 'pepperoni'}}, ] ) request_id2 = self.client.send_request( 'test_service', [ {'action': 'test_action_1', 'body': {'pizza': 'cheese'}}, ] ) self.assertIsNotNone(request_id1) self.assertIsNotNone(request_id2) responses = list(self.client.get_all_responses('test_service')) self.assertEqual(2, len(responses)) response_dict = {k: v for k, v in responses} self.assertIn(request_id1, response_dict) self.assertIn(request_id2, response_dict) response = response_dict[request_id1] self.assertIsNotNone(response) self.assertEqual([], response.errors) self.assertEqual(2, len(response.actions)) self.assertEqual([], response.actions[0].errors) self.assertEqual({'look': 'menu'}, response.actions[0].body) self.assertEqual({'pepperoni': 'pizza'}, response.actions[1].body) response = response_dict[request_id2] self.assertIsNotNone(response) self.assertEqual([], response.errors) self.assertEqual(1, len(response.actions)) self.assertEqual([], response.actions[0].errors) self.assertEqual({'cheese': 'pizza'}, response.actions[0].body) stub_test_action_1.assert_has_calls( [ mock.call({'menu': 'look'}), mock.call({'pizza': 'pepperoni'}), mock.call({'pizza': 'cheese'}), ], any_order=True, )
def test_send_unix(self): with mock.patch.object(socket.socket, 'connect') as mock_connect: handler = SyslogHandler(address='/path/to/unix.socket') mock_connect.assert_called_once_with('/path/to/unix.socket') with mock.patch.object(socket.socket, 'send') as mock_send: handler._send(['this is the first part', 'here is another part', 'one more part']) mock_send.assert_has_calls([ mock.call('this is the first part'), mock.call('here is another part'), mock.call('one more part'), ])
def _assert_mock_expectations(test_target): if 'mock_patches' in test_target: for mock_target, config in six.iteritems(test_target['mock_patches']): if 'magic_mock' in config: for path, expectations in six.iteritems(config['expectations']): obj = config['magic_mock'] if path: for entry in path.split('.'): obj = getattr(obj, entry) actual_calls = obj.call_count if expectations['not_called']: assert actual_calls == 0, ( 'Expected mock to not have been called. Called {} times.'.format(actual_calls), ) elif expectations['calls']: obj.assert_has_calls( [unittest_mock.call(*value[0], **value[1]) for value in expectations['calls']] ) expected_calls = len(expectations['calls']) assert actual_calls == expected_calls, ( 'Expected mock to be called {expected} times. Called {actual} times.'.format( expected=expected_calls, actual=actual_calls ), )
def test_as_decorator_with_patch_after(self, stub_test_action_2, mock_randint): stub_test_action_2.side_effect = ({'value': 122}, {'also': 157}) response = self.client.call_actions( 'test_service', [{'action': 'test_action_1'}, {'action': 'test_action_2'}, {'action': 'test_action_2'}], ) self.assertEqual(3, len(response.actions)) self.assertEqual({'value': 7}, response.actions[0].body) self.assertEqual({'value': 122}, response.actions[1].body) self.assertEqual({'also': 157}, response.actions[2].body) self.assertEqual(2, stub_test_action_2.call_count) self.assertEqual(({}, {}), stub_test_action_2.call_bodies) stub_test_action_2.assert_has_calls([mock.call({}), mock.call({})]) mock_randint.assert_called_once_with(0, 99)
def test_send_tcp(self): with mock.patch.object(socket.socket, 'connect') as mock_connect: handler = SyslogHandler( address=('127.0.0.1', logging.handlers.SYSLOG_UDP_PORT), socket_type=socket.SOCK_STREAM, ) mock_connect.assert_called_once_with(('127.0.0.1', logging.handlers.SYSLOG_UDP_PORT)) with mock.patch.object(socket.socket, 'sendall') as mock_send_all: handler._send(['this is the first part', 'here is another part', 'one more part']) mock_send_all.assert_has_calls([ mock.call('this is the first part'), mock.call('here is another part'), mock.call('one more part'), ])
def _assert_stub_expectations(test_target): if 'stubbed_actions' in test_target: for stub_config in six.itervalues(test_target['stubbed_actions']): if 'mock_action' in stub_config: if 'expect_request' in stub_config: stub_config['mock_action'].assert_has_calls([ unittest_mock.call(stub_config['expect_request']), ]) elif 'expect_not_called' in stub_config: assert stub_config['mock_action'].call_count == 0
def test_send_receive_one_stub_one_real_call_mixture( self, stub_test_action_1): stub_test_action_1.side_effect = ( ActionResponse(action='does not matter', body={'look': 'menu'}), ActionResponse(action='no', errors=[ Error(code='WEIRD', field='pizza', message='Weird error about pizza') ]), ActionError(errors=[Error(code='COOL', message='Another error')]), ) request_id1 = self.client.send_request( 'test_service', [ { 'action': 'test_action_1', 'body': { 'menu': 'look' } }, { 'action': 'test_action_2' }, { 'action': 'test_action_1', 'body': { 'pizza': 'pepperoni' } }, { 'action': 'test_action_2' }, { 'action': 'test_action_2' }, ], continue_on_error=True, ) request_id2 = self.client.send_request('test_service', [ { 'action': 'test_action_1', 'body': { 'pizza': 'cheese' } }, ]) request_id3 = self.client.send_request('test_service', [ { 'action': 'test_action_2' }, ]) self.assertIsNotNone(request_id1) self.assertIsNotNone(request_id2) self.assertIsNotNone(request_id3) responses = list(self.client.get_all_responses('test_service')) self.assertEqual(3, len(responses)) response_dict = {k: v for k, v in responses} self.assertIn(request_id1, response_dict) self.assertIn(request_id2, response_dict) self.assertIn(request_id3, response_dict) response = response_dict[request_id1] self.assertIsNotNone(response) self.assertEqual([], response.errors) self.assertEqual(5, len(response.actions)) self.assertEqual([], response.actions[0].errors) self.assertEqual({'look': 'menu'}, response.actions[0].body) self.assertEqual([], response.actions[1].errors) self.assertEqual({'value': 0}, response.actions[1].body) self.assertEqual( [ Error(code='WEIRD', field='pizza', message='Weird error about pizza') ], response.actions[2].errors, ) self.assertEqual([], response.actions[3].errors) self.assertEqual({'value': 0}, response.actions[3].body) self.assertEqual([], response.actions[4].errors) self.assertEqual({'value': 0}, response.actions[4].body) response = response_dict[request_id2] self.assertIsNotNone(response) self.assertEqual([], response.errors) self.assertEqual(1, len(response.actions)) self.assertEqual([Error(code='COOL', message='Another error')], response.actions[0].errors) response = response_dict[request_id3] self.assertIsNotNone(response) self.assertEqual([], response.errors) self.assertEqual(1, len(response.actions)) self.assertEqual([], response.actions[0].errors) self.assertEqual({'value': 0}, response.actions[0].body) stub_test_action_1.assert_has_calls( [ mock.call({'menu': 'look'}), mock.call({'pizza': 'pepperoni'}), mock.call({'pizza': 'cheese'}), ], any_order=True, )