jeudi 23 juillet 2020

Ensure cleanup code runs in an async QUnit context

I am trying to understand how to implement clean-up code after a QUnit test which involves an event being triggered asynchronously.

I have seen this answer. But for one thing, try as I might, I don't understand how I can apply this to my case, and secondly it is using the "old" QUnit approach to async handling (start and stop...).

Say I have the following test, which is trying to verify that something happens when the innerText of a page element changes, triggering a mutation event on a MutationObserver:

QUnit.test( 'when the mutation observer reacts ... do something',
    function( assert ){
        console.log( `---------------\nrunning: ${assert.test.testName}\n---------------` );

        try{
            // switch on the MutationObserver...
            Global.dbCompObserver.observe( document, Global.dbCompObserver.config );

            const compX = document.createElement( 'DIV' );
            // by appending it to the body, since the MutationObserver is observing things
            // which happen in the document, a change to the comp will trigger a mutation event
            document.body.appendChild( compX );

            const udv = new UDV();
                
            const done = assert.async();
            udv.update = function(){
                done();
                assert.ok( true );
                // cleanup code... if udv.update is actually called...
                Global.dbCompObserver.disconnect();
                document.body.removeChild( compX );
            };
            assert.expect( 1 );
            // this triggers a MutationEvent... but that function call is async
   *         compX.innerText = 'some new text';
            //

        }finally {
            /* this is where I usually put my cleanup code, with simpler tests
... but I have no idea how to implement cleanup code if, for example, udv.update fails to be called...
            */
        }
});

If the "mock" update method above is called the clean-up happens... but how to clean up otherwise? You can't put the clean-up code in the finally block because that will result in failure of the test: the MutationObserver would be switched off immediately after setting comp.innerText, and before the asynchronous mutation event actually ran.

Aucun commentaire:

Enregistrer un commentaire