jeudi 19 novembre 2015

How to unittest an raised exception after looping with mock

I'm trying to test the raise exception portion after my loop exits. I'm using mock and pytest and I'm not sure how to approach it. I'm trying to avoid adding the same type of loop to my test code. I'm setting mock side_effect of an exception on the function call then once that loop completes I'm want to assert that the raise did indeed raise the expected exception. All I'm trying to do is add test coverage to the exit of my loop.

function under test

def set_kv(self, key, value):
    for _ in range(0, 20):
        try:
            return self.client.kv.put(key, value)
        except (ConnectionError, ConsulException):
            sleep(1)
            continue

    LOGGER.error('Failed setting key "%s" with value "%s"', key, value)
    raise

failing test

@patch('app.models.cluster.service.discovery.sleep', return_value=None)
def test_set_kv_exhausts_all_retries(self, mock_sleep, mock_kv, mock_consul):
    client = mock_consul.return_value
    client.kv = mock_kv
    client.kv.put.side_effect = ConnectionError()
    consul = Consul(HOST)

    try:
        response = consul.set_kv(KEY, VALUE)
    except ConnectionError:
        pass

    self.assertRaises(ConnectionError, response)

What happens here is that response actually looped 20 times and isn't finished by the time I check it's value with assertRaises. What's a better way to test that my loop exited and raise gets asserted?

Or is there a better way to think about testing this code?

Aucun commentaire:

Enregistrer un commentaire