Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QUESTION: Usage in monorepo #132

Open
kpeters-cbsi opened this issue Jun 2, 2022 · 4 comments
Open

QUESTION: Usage in monorepo #132

kpeters-cbsi opened this issue Jun 2, 2022 · 4 comments

Comments

@kpeters-cbsi
Copy link

I have a monorepo set up using yarn workspaces and Lerna. I've got a package inside the monorepo that sends messages to Slack, and I'd like to test it using this package. The package tests are located under <repo root>/packages/my-package/tests, but @slack/web-api is located under <repo root>/node_modules. I've tried creating a manual mock as described in the README in both <repo root>/packages/my-package/__mocks__ and <repo root>/__mocks__, but the below code still gives me an error: TypeError: Cannot read property 'chat' of undefined. What's the proper way to use this in a monorepo context?

Note that I'm using Typescript 4.7.2 and Node 14.19.0

import { handler as announcer } from "../lambda/announcer"
import { SNSEvent, Context } from "aws-lambda"
import { MockedWebClient, MockWebClient } from "@slack-wrench/jest-mock-web-client"

describe("Announcer", () => {
  let client: MockWebClient
  beforeEach(() => {
    MockedWebClient.mockClear()
    client = MockedWebClient.mock.instances[0]
  })

  it("Publishes a message to Slack", async () => {
    const recs = [
      { name: 'rec-1'  },
      { name: 'rec-2' }
    ]

    const event = {
      Records: recs.map((r) => ({
        Sns: {
          Message: JSON.stringify(r),
        },
      })),
    } as SNSEvent

    await expect(announcer(event, {} as Context, () => {})).resolves.not.toThrowError()
    expect(client.chat.postMessage).toHaveBeenCalledTimes(recs.length)
  })
})

@barlock
Copy link
Contributor

barlock commented Jun 5, 2022

It should work, this repo itself is a monorepo and uses it successfully. Though admittedly not directly anywhere.

From the looks of your code, I don't see anywhere between you clearing the mocks and trying to access an instance of a client where you are creating one. In order to see one in instances you need to have first created an instance. Usually this would be after instantiating a server or script. I would expect if you tried assigning client just after your await and before the failing expect that your test would pass.

@kpeters-cbsi
Copy link
Author

Thanks, I'll try that.

@kpeters-cbsi
Copy link
Author

So I updated my code like so:

import { handler as announcer } from "../lambda/announcer"
import { SNSEvent, Context } from "aws-lambda"
import { MockedWebClient, MockWebClient } from "@slack-wrench/jest-mock-web-client"

describe("Announcer", () => {
  let client: MockWebClient
  beforeEach(() => {
    MockedWebClient.mockClear()
  })

  it("Publishes a message to Slack", async () => {
    const recs = [
      { name: 'rec-1'  },
      { name: 'rec-2' }
    ]

    const event = {
      Records: recs.map((r) => ({
        Sns: {
          Message: JSON.stringify(r),
        },
      })),
    } as SNSEvent

    await expect(announcer(event, {} as Context, () => {})).resolves.not.toThrowError()
    client = MockedClient.mock.instances[0]
    expect(client.chat.postMessage).toHaveBeenCalledTimes(recs.length)
  })
})

And I got the same error.

Here's the basic code for announcer():

import { SNSHandler } from "aws-lambda"
import { WebClient } from "@slack/web-api

export const handler: SNSHandler = async (event, context) => {
  const config = await getConfig()
  if (!config.slack_oauth_token) {
    throw new Error("No slack_oauth_token found in config")
  }
  const webclient = new WebClient(config.slack_oauth_token)
  await Promise.allSettled(
    event.Records.map(async (record) => {
     const response = {}
      // ... do stuff with record
      return response
    })
  )
}

As you can see, I'm instantiating WebClient in announcer()

@nadirabbas
Copy link

@kpeters-cbsi Did you find a solution to this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants