How to catch output of reponse.write in a test?


I just uncovered a method which failed on Python 3 for using response.write with str-input and failed with a TypeError: a bytes-like object is required, not 'str'.

The fix was easy, but I cannot figure out how to capture what gets written by response.write in order to use it for my test's assert statement.

Anybody has a clue?

The method looks like that:

    def reindexIndex(self, REQUEST=None):
        """ reindex a single index at a catalog """
        response = REQUEST.RESPONSE
        response.setHeader("Content-Type", "text/plain")
        response.write(b"Reindexing Index...\n")
        cat = self.classCatalog(REQUEST.className)
        cat.reindexIndex(REQUEST.indexName, REQUEST)

The test looks like...

    rv = mm.reindexIndex(request)
    assert ???

I cannot "find" the DONE neither by introspecting request nor response.

1 Like

Maybe, the services of unittest.mock (part of Python's standard library) can help you. They are designed to implement mock objects for test purposes and support analysis on how they have been used during the test.

1 Like

What is the purpose of your reindexIndex implementation? What do you want to check? If the method works then it will not raise any error and return a related HTTP status code 200

@dieter, thank you. I hoped it would be possible without the usage of mock, but if not, this is certainly a good use case.

(I had some bad experiences with awkward design and then heavy usage of mock, and since then I try to avoid mock unless really necessary, e.g for external network calls...).


Huh, where do I start?

Catalogs (there is one for each model class), indexes (there is one for each attribute), ... are managed via UML :partying_face:

Let's say, I add a new attribute shoe_size for Person in the UML, the script (view in Zope), which parses the UML, issues a warning a la "Added index 'shoe_size' to class 'Person' - You need to (link to reindexindex)reindex(link) the index: shoe_size. Then I click the link and see the output of "reindexindex".

I think it is probably ok, that the reindex does not directly get triggered by the parse_uml script, as otherwise this could take pretty long (or maybe I should do this automatically, so there is no chance to forget about clicking the link).

But I am pretty sure, one could construct an URL to trigger the reindex via a call to ZMI and thus there is no need for a custom method.

P.S.: This is all inherited code, and yes, I'd like to get rid of the UML completely, have done already some steps towards the removal, but this is not a top priority and will much more time.

TL/DR It is a web view - so I see the output (and also the error message, if there is a problem).