docs.nestjs.com icon indicating copy to clipboard operation
docs.nestjs.com copied to clipboard

Documentation about "Testing request scoped instances" does not apply to GraphQL setups

Open antoniusostermann opened this issue 4 years ago • 3 comments

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

I was trying to do a GraphQL-based E2E spec with request scoped providers. To be able to resolve the same request-scoped provider instances in my test as they are used by nestjs when fulfilling the request, I followed https://docs.nestjs.com/fundamentals/testing#testing-request-scoped-instances. Unfortunately, I noticed that the suggested spyOn(ContextIdFactory, 'getByRequest') was never triggered. Digging into the source code, I found out that ContextIdFactory.getByRequest() is only called by Nest when using regular controllers (link to source code). When using @nestjs/graphql, the contextId is actually taken from gqlContext[REQUEST_CONTEXT_ID] || gqlContext.req[REQUEST_CONTEXT_ID] or created otherwise using createContextId() (link to source code).

Attaching my contextId to gqlContext[REQUEST_CONTEXT_ID] actually solved my issue.

Expected behavior

Since the "testing request scoped instances" headline is placed in the "fundamentals" section, I thought it would apply to all kind of NestJS specs, whether I use GraphQL or not. If this is intended, I would expect a hint that this approach does not work for graphql requests and some additional best practice / guideline about how to achieve this with graphql. As an alternative, maybe we could suggest setting request[REQUEST_CONTEXT_ID] directly instead of spying on ContextIdFactory.getByRequest. If I understood the source code correctly, this would work for both graphql and regular http requests.

antoniusostermann avatar Aug 24 '21 17:08 antoniusostermann

@antoniusostermann - Could you please provide an example of a test that sets the contextId to the gqlContext (or the request)?

sethew avatar Dec 30 '21 20:12 sethew

@sethew I guess you could ask this on https://discord.gg/nestjs

micalevisk avatar Dec 30 '21 21:12 micalevisk

I've discovered the same and this is the workaround I'm using for now:

beforeEach(async () => {

  //creating a contextId     
  const contextId = ContextIdFactory.create()
  const moduleFixture: TestingModule = await Test.createTestingModule({
    imports: [
    ///.... other modules imported here
      GraphQLModule.forRoot<ApolloDriverConfig>({
          driver: ApolloDriver,
          context: ({ req }) => {
              req[REQUEST_CONTEXT_ID] = contextId //adding the context id to the request object
              return {
                  req: req,
              }
          },
      }),
    ]
    //rest of module definition
  })
})

vizio360 avatar Jun 20 '22 12:06 vizio360