Search code examples
javascriptnode.jsava

t.context scoping in ava


I'm 90% sure of what is causing the problem but I'd like to clarify how ava handles t.context. Here is my scenario:

const lMockManager = ImportMock.mockClass<zmq.Dealer>(zmq, "Dealer");
lMockManager.mock(Symbol.asyncIterator, lNewIterator);

test.before((t: ExecutionContext<TTestContext) =>
{
    t.context =
    {
        DummyData: [],
        PromiseCallback: null,
        ZMQMock: lMockManager,
    };

    const lNewIterator = (() =>
    {
        return {
            async next()
            {
                return new Promise((resolve: (aValue: string[]) => void): void =>
                {
                    t.context.PromiseCallback = resolve;
                });
            },
        };
    })();

});

test("Receive Message", (t: ExecutionContext<TTestContext) =>
{
    const lMessageReceiver = new MessageReceiver();  // Imports ZMQ as a dep
    lMessageReceiver.Start();  // This triggers the creation of t.PromiseCallback

    t.context.PromiseCallback("hello world"); // Error: t.context.PromiseCallback is null
});

For testing purposes I pushed test.before()'s t.context into a global object and compared it against test()'s t.context and confirmed that the objects are indeed different. So I assume test() is passed a deepCopy of t.context.

This makes sense to avoid having test() modify the shared t.context. So this behaviour combined with me setting lNewIterator inside test.before(), means that I modify the shared t.context after the test starts but because each test has a local deep copy, they do not received the modifications.

I will setup lNewIterator within test() as modifying the shared t.context after test.before() exits seems like an anti-pattern.


Solution

  • t.context from test.before() is indeed copied, though shallowly. Try storing the callback on an object like t.context.callback = { fn: null } or something along those lines.

    Looking at your injection code I think you may be better off using serial tests and beforeEach() hooks.