cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.48k stars 3.2k forks source link

Create A Better Testing Solution For Angular Services #26243

Closed lmiller1990 closed 1 year ago

lmiller1990 commented 1 year ago

Goal

Note: based on https://github.com/cypress-io/cypress-internal/issues/544

Currently we provide an excellent tool for testing Angular Components using the mount function. We need to provide a better solution for Angular Services.

Why

According the Angular Documentation, Angular distinguishes components from services to increase modularity and reusability.. A component should use services for tasks that don't involve the view or application logic. This means that though we provide an excellent tool for testing components we are missing a key piece of the puzzle in Angular Services.

This is important because:

  1. Angular Adoption has been identified as import to CT adoption
  2. This has been a common question I've been asked while doing advocacy for Angular CT

Implementation

I have a working implementation you can see here.

The current implementation includes an inject and a invokeService method. The pain is mostly caused because Angular relies heavily on RxJs Observables and (soon signals). This means that our Command Chain doesn't intuitively play nice with Angular Services.

This is how you would go about testing this currently:

cy.intercept('GET', '/count', { count: 5 }).then(async () => {
     TestBed.configureTestingModule({
      providers: [CountService],
      imports: [HttpClientModule]
     })

     const countService = TestBed.inject(CountService);
     const response = await firstValueFrom(countService.getCount())
     expect(response).equal(5)
  })

What I'm proposing:

cy.intercept('GET', '/count', { count: 5 }).then(() => {
    cy.inject(CountService).invokeService('getCount').should('equal', 5)
})

Questions

  1. Do we want this to be a first party thing we expose as part of the cypress/angular lib?
  2. Do we want this to be a plugin we want to create?
  3. Do we wish to solve this via documentation? (easiest but worst DX)

Topic

Dependencies

Research

Topic

Several Issues that have been created around this request:

jordanpowell88 commented 1 year ago

Ideally we would at the very least provide the inject function as part of the npm/angular lib as it would be valuable for Angular users doing traditional Component Testing. See #25505

rainerhahnekamp commented 1 year ago

I wouldn't focus on Angular's DI feature only. The scope is much larger. It is not just about the TestBed's inject function but also overrideComponent (and flavours), detectChanges, controlling asynchrony (cy.clock doesn't work), and other TestBed-related features: https://angular.io/api/core/testing/TestBed

Questions for those features haven't shown up yet because Cypress component testing is relatively young and not yet used that much.

I don't really see the benefit of creating Cypress commands that are just proxies to the methods of the TestBed. So I would tend to improve the documentation and ensure everybody understands how to access the TestBed properly.

cypress-app-bot commented 1 year ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

cypress-app-bot commented 1 year ago

This issue has been closed due to inactivity.