help-me-mom / ng-mocks

Angular testing library for mocking components, directives, pipes, services and facilitating TestBed setup
https://www.npmjs.com/package/ng-mocks
MIT License
1.04k stars 75 forks source link

Bug: Incompatibility of MockComponent with new viewChild signal function #8634

Open mh-ahs opened 5 months ago

mh-ahs commented 5 months ago

Description of the bug

Testing standalone components with nested components that use the new viewChild signal feature is currently not possible if the nested component should be mocked.

I'm not sure if ngMocks can do anything about it or if its an angular-core related problem.

An example of the bug

Link: https://stackblitz.com/edit/github-6eneyd?file=src%2Ftest.spec.ts I added a "NestedComponent" to the default example and replaced the module-based definitions with a simple standalone definition.

Expected vs actual behavior

Using the Signal implementation leads to TypeError: Cannot read properties of undefined (reading 'Symbol(SIGNAL)') Switching the implementation from Signal to Decorator lets test run fine,

GipHub123 commented 5 months ago

I can confirm this one đź‘Ť Having same problems after the change.

c-harding commented 5 months ago

Temporary workaround: use MockBuilder#replace

@Component({
  selector: 'app-nested',
  standalone: true,
  template: ``,
})
class NestedComponentStub {
  public readonly anchor = signal(new ElementRef(undefined)).asReadonly();
  public readonly name = input.required<string>();
}

describe('my sandbox', () => {
  beforeEach(() =>
    MockBuilder(TargetComponent).replace(NestedComponent, NestedComponentStub)
  );
c-harding commented 5 months ago

@satanTime this seems to be a better fix: simply remove the view queries, as they’ll always be null anyway

https://github.com/help-me-mom/ng-mocks/blob/282cbf0a6d1bb3ae78c6c8fb48f753bb02ca8d33/libs/ng-mocks/src/lib/common/decorate.queries.ts#L22-L39

  const generateFinalQueries = (queries: { 
    [key: string]: Query; 
  }): [Array<[string, Query & { ngMetadataName?: string }]>, string[]] => { 
    const final: Array<[string, Query & { ngMetadataName?: string }]> = []; 
    const scanKeys: string[] = []; 

    for (const key of Object.keys(queries)) { 
      const query: Query & { ngMetadataName?: string } = queries[key]; 
-     final.push([key, query]); 

      if (!query.isViewQuery && !isInternalKey(key)) { 
+       final.push([key, query]);
        scanKeys.push(key); 
        final.push([`__ngMocksVcr_${key}`, cloneVcrQuery(query)]); 
      } 
    } 

    return [final, scanKeys]; 
  }; 
andreandersson commented 4 months ago

This will be fixed by the same fix as https://github.com/help-me-mom/ng-mocks/issues/7976, is my guess.

renanaragao commented 4 months ago

Good evening, any news?

mishahrokhola commented 4 months ago

Hello, any updates on this issue?

LukasMachetanz commented 4 months ago

I guess #8895 is a similar problem.

LukasMachetanz commented 3 months ago

Any news on this issue? This bug really prevents using the new API.

SereetsiKC commented 3 weeks ago

The fix here is not to mock the component but pass it into your test declarations with you parent component

satanTime commented 2 weeks ago

Sorry for the delay. I'll take a look closer next week.