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.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With