How to use assertRaises in a trial test case using inlineCallbacks
Asked Answered
W

1

12

I'm trying to figure out how to write a trial test case which asserts an exception is raised.

Currently I have 2 simple methods to test (success and failure). Each method returns a deferred which has already been either callback'd or errback'd. Testing the success method works fine. When testing the failure method I expect to be able to assert that an exception was raised (using assertRaises).

However the test case fails and I get:

twisted.trial.unittest.FailTest: ConnectionRefusedError not raised (<Deferred at 0x920e28c current result: <twisted.python.failure.Failure <class 'twisted.internet.error.ConnectionRefusedError'>>> returned)

The code is as follows:

from twisted.trial.unittest import TestCase
from twisted.internet.defer import inlineCallbacks, succeed, fail
from twisted.internet.error import ConnectionRefusedError

class MyObject:
    def success(self):
        return succeed(True)

    def failure(self):
        return fail(ConnectionRefusedError())


class TestErrBack(TestCase):
    def setUp(self):
        self.o = MyObject()

    @inlineCallbacks
    def test_success(self):
        result = yield self.o.success()
        self.assertTrue(result)

    @inlineCallbacks
    def test_failure(self):
        # this test case is failing !
        yield self.assertRaises(ConnectionRefusedError, self.o.failure)

Am I using the right approach in test_failure ? I can use try...catch around the call to self.o.failure, but I don't think this approach is as good as using assertRaises.

Wolfie answered 23/3, 2012 at 14:23 Comment(0)
D
14

Use TestCase.assertFailure instead:

yield self.assertFailure(self.o.failure(), ConnectionRefusedError)

Starting in Twisted 12.3, there's also a TestCase.failureResultOf helper:

self.failureResultOf(self.o.failure()).trap(ConnectionRefusedError)

And starting in 13.1 this API takes an additional argument and performs type checking for you:

self.failureResultOf(self.o.failure(), ConnectionRefusedError)

This is useful for tests where you know the Deferred has already fired with a result. If the Deferred does not have a failure result at the time of the call, failureResultOf raises a test-failing exception instead of returning the failure.

This will work fine for your example code and should be applicable to most unit tests. If you're using trial to write functional or integration tests where there is actual asynchronous work going on and you don't know when the Deferred will fire then you need to stick with the first API, assertFailure.

Devaney answered 23/3, 2012 at 20:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.