testPublish() {
    mockHTML5LocalStorageCtor().$returns(mockHtml5LocalStorage);
    const foo = mockControl.createFunctionMock();
    foo('x', 'y');

    const context = {'foo': 'bar'};
    const bar = recordFunction();

    const baz = mockControl.createFunctionMock();
    baz('d', 'c');

    mockControl.$replayAll();
    broadcastPubSub = new BroadcastPubSub();
    log.setLevel(broadcastPubSub.logger_, Level.OFF);

    broadcastPubSub.subscribe('someTopic', foo);
    broadcastPubSub.subscribe('someTopic', bar, context);
    broadcastPubSub.subscribe('anotherTopic', baz, context);

    broadcastPubSub.publish('someTopic', 'x', 'y');
    mockClock.tick();

    assertTrue(broadcastPubSub.unsubscribe('someTopic', foo));

    broadcastPubSub.publish('anotherTopic', 'd', 'c');
    broadcastPubSub.publish('someTopic', 'x', 'y');
    mockClock.tick();

    broadcastPubSub.subscribe('differentTopic', foo);

    broadcastPubSub.publish('someTopic', 'x', 'y');
    mockClock.tick();

    assertEquals(3, bar.getCallCount());
    bar.getCalls().forEach(call => {
      assertArrayEquals(['x', 'y'], call.getArguments());
      assertEquals(context, call.getThis());
    });
    broadcastPubSub.dispose();
    mockControl.$verifyAll();
  }
The following tests are duplicated from pubsub because they depend
on functionality (mostly "publish") that has changed in BroadcastChannel.
@suppress {checkTypes,visibility} suppression added to enable type checking