CreateSpyObject 在“beforeEach”中有效,但在“it”中无效

问题描述 投票:0回答:1

我有一个组件:

@Component({
  selector: 'app-sidenav',
  standalone: true,
  imports: [
    MatSidenavModule
  ],
  templateUrl: './sidenav.component.html',
  styleUrl: './sidenav.component.scss'
})
export class SidenavComponent implements OnInit {

  openingService = inject(SidenavOpeningService);
  opened: BooleanInput;

  #injector = inject(Injector);
  constructor() {
  }

  ngOnInit():void {
    runInInjectionContext(this.#injector, () => {
      effect(() => {
        this.opened = this.openingService.isOpen();
      });
    });
  }

}

<mat-sidenav-container>
  <mat-sidenav #sidenav [opened]="opened" (openedChange)="openingService.isOpen.set($event)"  mode="over">Start</mat-sidenav>
  <mat-sidenav-content>
    <p>test</p>
  </mat-sidenav-content>
</mat-sidenav-container>

还有服务:

import {Injectable, signal} from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SidenavOpeningService {
  isOpen = signal(false);


  constructor() { }

  toggle() {
    this.isOpen.update(value => !value);
  }

}

本次测试通过:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SidenavComponent } from './sidenav.component';
import {SidenavOpeningService} from "../../services/sidenav-opening.service";
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import {MatSidenavModule} from "@angular/material/sidenav";

describe('SidenavComponent', () => {
  let component: SidenavComponent;
  let fixture: ComponentFixture<SidenavComponent>;
  let mockService: jasmine.SpyObj<SidenavOpeningService> = jasmine.createSpyObj('SidenavOpeningService', ['isOpen', 'toggle']);


  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [SidenavComponent,MatSidenavModule, NoopAnimationsModule],
      providers: [{ provide: SidenavOpeningService, useValue: mockService }]
    })
    .compileComponents();

    fixture = TestBed.createComponent(SidenavComponent);
    component = fixture.componentInstance;
    mockService.isOpen.and.returnValue(true);
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should update "opened" based on SidenavOpeningService', () => {
    expect(component.opened).toBeTrue();
  });
});

但是这个测试没有通过:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SidenavComponent } from './sidenav.component';
import {SidenavOpeningService} from "../../services/sidenav-opening.service";
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import {MatSidenavModule} from "@angular/material/sidenav";

describe('SidenavComponent', () => {
  let component: SidenavComponent;
  let fixture: ComponentFixture<SidenavComponent>;
  let mockService: jasmine.SpyObj<SidenavOpeningService> = jasmine.createSpyObj('SidenavOpeningService', ['isOpen', 'toggle']);


  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [SidenavComponent,MatSidenavModule, NoopAnimationsModule],
      providers: [{ provide: SidenavOpeningService, useValue: mockService }]
    })
    .compileComponents();

    fixture = TestBed.createComponent(SidenavComponent);
    component = fixture.componentInstance;
    
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should update "opened" based on SidenavOpeningService', () => {
    mockService.isOpen.and.returnValue(true);
    fixture.detectChanges();
    expect(component.opened).toBeTrue();
  });
});

我有:期望未定义为真。 在 在 UserContext.apply (src/app/core/components/sidenav/sidenav.component.spec.ts:32:30) 在 _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:368:26) 在 ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:273:39) 在 _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:367:52)

angular signals karma-runner
1个回答
0
投票

我们需要初始化组件,在设置茉莉花间谍后,这可以修复故障!

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MatSidenavModule } from '@angular/material/sidenav';
import { SidenavComponent } from './sidenav-responsive-example';
import { SidenavOpeningService } from './sidenav-opening.service';

describe('SidenavComponent', () => {
  let component: SidenavComponent;
  let fixture: ComponentFixture<SidenavComponent>;
  let mockService: jasmine.SpyObj<SidenavOpeningService> = jasmine.createSpyObj(
    'SidenavOpeningService',
    ['isOpen', 'toggle']
  );

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [SidenavComponent, MatSidenavModule, NoopAnimationsModule],
      providers: [{ provide: SidenavOpeningService, useValue: mockService }],
    }).compileComponents();

    fixture = TestBed.createComponent(SidenavComponent);
    component = fixture.componentInstance;

    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should update "opened" based on SidenavOpeningService', () => {
    mockService.isOpen.and.returnValue(true);

    fixture = TestBed.createComponent(SidenavComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    expect(component.opened).toBeTrue();
  });
});

stackblitz demo ->

ctrl+C
终止终端中的默认命令 ->
npm run test
启动测试用例!

© www.soinside.com 2019 - 2024. All rights reserved.