PubSub testing in NodeJS testing with Emulator fails - requires a project but doesn't set one

Viewed 422

I'm trying to test the PubSub emissions locally on my NodeJS app. I'm following these tutorials: https://cloud.google.com/pubsub/docs/emulator - setting the Emulator https://cloud.google.com/functions/docs/testing/test-event - app specific

As instructed in the first link, I started the emulator by invoking: gcloud beta emulators pubsub start --project=test, and set the env variables by $(gcloud beta emulators pubsub env-init).

But in contrast to what appears in the tutorial, when I check which env variables needs to be set by gcloud beta emulators pubsub env-init, there is no project-id. And as I run the test I receive the following error: Unable to detect a Project Id in the current environment...

So I tried to set a project manually by invoking gcloud config set project test.

the tutorial specifies about the project parameter ('test' in my case):

The string does not need to represent a real Google Cloud project because the Pub/Sub emulator runs locally.

However, as I run the test, it now gives the following error: 5 NOT_FOUND: Requested project not found or user does not have access to it (project=test)...

*In both cases, the error comes from the publish function

What can I do in this case? Must I use an existing project in oppose to what's claimed in the tutorial, or else what am I missing?

The test:

describe('SubscribeController', () => {
  const pubSub = new PubSub();
  let subscribeController: SubscribeController;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [
        {
          provide: LoggerService,
          useValue: {},
        },
      ],
      controllers: [SubscribeController],
    }).compile();

    subscribeController = moduleRef.get<SubscribeController>(SubscribeController);
  });

  describe('1 emissions tests', () => {
    it('1.1 when receives an event emission, should log via the LoggerService', async () => {
      const logEventMock = jest.spyOn(subscribeController, 'logEvent').mockImplementation(async function(event:string) {});
      const topic = pubSub.topic('EVENT');
      await topic.publish(Buffer.from('hello'));
      await logEventMock.mock.results[0].value;
      expect(logEventMock).toHaveBeenCalledWith('hello');
    });
  });
});

The tested subject:

@Controller()
export class SubscribeController {
  constructor(private readonly _loggerService: LoggerService) {
  }

  @EventPattern('EVENT')
  async logEvent(event: string): Promise<void> {
    await this._loggerService.logEvent(event);
  }

  @EventPattern('ERROR')
  async logError(error: string): Promise<void> {
    await this._loggerService.logError(error);
  }
}

PubSub dependency in package.json:

  "dependencies": {
    "@google-cloud/pubsub": "^2.17.0",
    ...
  }
1 Answers

You need first to start the emulator with this code:

gcloud beta emulators pubsub start --project=test

Then, you need to run your code. If you didn’t start the emulator, you’ll get this error: The string does not need to represent a real Google Cloud project because the Pub/Sub emulator runs locally.

If you still get the error Unable to detect a Project Id in the current environment, execute this command: gcloud info, which will show you the account and project you are using. And with this command: gcloud projects list, you’ll be able to see the available projects for your account. Then use this command: gcloud config set project test to set a real project. After that, you can follow the tutorial.

Your API needs to connect with the parameters of the emulator. Port=8085 and localhost(127.0.1).

You can see this documentation about testing apps locally with the emulator.

Related