Running same test twice lead to following error: Mock "port.onMessage" has been used after tests have finished!
As already discussed in #13 I have followng code to be tested
import browser from 'webextension-polyfill'
export class GithubMockzillaMessaging {
public connect(): void {
browser.runtime.onConnect.addListener((port: browser.Runtime.Port) => {
port.onMessage.addListener((message): void => {
port.postMessage(`${message}: reply`)
})
})
}
}
My unit test is following
import 'mockzilla-webextension'
// import of mockzilla-webextension before(!) actual import of 'webextension-polyfill' in system-under-test
import { mockEvent, MockzillaEventOf } from 'mockzilla-webextension'
import { deepMock } from 'mockzilla'
import { Runtime } from 'webextension-polyfill'
import { GithubMockzillaMessaging } from './../src/GithubMockzillaMessaging'
describe('BackgroundScriptMessaging', () => {
const [port, mockPort, mockPortNode] = deepMock<Runtime.Port>('port')
let msgs = new Array()
let addListenerOnConnect: MockzillaEventOf<typeof mockBrowser.runtime.onConnect>
let addListenerOnMessage: MockzillaEventOf<typeof mockPort.onMessage>
beforeEach(() => {
addListenerOnConnect = mockEvent(mockBrowser.runtime.onConnect)
addListenerOnMessage = mockEvent(mockPort.onMessage)
})
describe('MessagingBackgroundScript function test', () => {
it('method connect() shall handle connection request', async () => {
mockPort.postMessage.expect('test-message: reply')
const sut = new GithubMockzillaMessaging()
sut.connect()
addListenerOnConnect.emit(port)
addListenerOnMessage.emit('test-message', port)
})
it('method connect() shall handle more connection requests', async () => {
mockPort.postMessage.expect('test-message-2: reply')
const sut = new GithubMockzillaMessaging()
sut.connect()
addListenerOnConnect.emit(port)
addListenerOnMessage.emit('test-message-2', port)
})
})
})
The unit test code shall test several cases of the code. When the unit test code is executed with just one it()-case it works without errors. Adding - as shown above - a second it()-case the unit test execution breaks for second it()-case with following error
Mock "port.onMessage" has been used after tests have finished!
What did I miss? Thank you
Without looking at the rest of your code, I would assume, that you have asynchronous code, which continues running after the test function has completed. You'd have to stop that asynchronous code somehow.
The code above is everything to be tested. It opens a messaging connection waiting. As soon as a message is received it replies sending back the received message appending the string ": reply". Running two UTs against this code the behaviour described above is triggered: Mock "port.onMessage" has been used after tests have finished!
As the first UT is passed and the second one complains, I thought maybe the mock-up must be "async" and maybe awaited...but here I'm kind of lost. Or maybe the first UT has to await "something" as the error says the mock port.onMessage has been used after tests have finished?
Sorry, I must have overlooked something back then. Your port mock needs to be disabled and enabled manually:
beforeEach(() => mockPortNode.enable());
afterEach(() => mockPortNode.verifyAndDisable());
See: https://lusito.github.io/mockzilla/deep-mock.html#solution
I guess the API could be written more comfortable for this scenario. Maybe like this:
mockEvent(mockBrowser.runtime.onConnect, true);
or:
mockEvent(mockBrowser.runtime.onConnect, { autoCleanup: true });
Great, works :).
Does that mean, the "Node"-object of a mocked object always requires to be called like this with enable() and verifyAndDisable()?
Aside from the mockbrowser one, which is preconfigured, yes.