typescript 表达式在检查后已更改,使用jasmine测试Angular 2分量时出错

ryoqjall  于 2022-11-18  发布在  TypeScript
关注(0)|答案(5)|浏览(147)

我在测试从服务接收可观察值的组件时遇到错误,我尝试在规范中模拟该行为,但遇到以下错误:表达式在选中后已更改,上一个值为“”,当前值为:[object Object]。请您帮我一下。我的规格文件如下:

import { ManualProcessService } from '../../services/manual-process.service';
import { ManualProcessComponent } from './manual-process.component';
import { MANUALPROCESSMOCKDATA } from '../../shared/mocks/mock-manualprocessdata';
import {DataTableModule, SharedModule, DropdownModule as PrimeNgDropDownModule, CheckboxModule, InputTextModule} from 'primeng/primeng';
import {MenuModule} from 'primeng/components/menu/menu';
import {DropdownModule} from 'ng2-bootstrap';
import { PopoverModule } from 'ng2-popover';
import {Observable} from 'rxjs/Observable';
import { IManualProcessData} from '../../models/manual-process.model';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {
  async,
  TestBed,
  fakeAsync,
  tick,
} from '@angular/core/testing';

class MockManualProcessService {

  getManualProcessData(): Observable<IManualProcessData> {
      return Observable.of(MANUALPROCESSMOCKDATA);
  }
}

describe('Testing Manual Process Component', () => {

  let fixture,
  event = {
    first: 0,
    rows: 10
  }, 
  manualProcessService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        ManualProcessComponent
      ],
      providers: [
        { provide: ManualProcessService, useClass: MockManualProcessService }
      ],
      imports: [
        FormsModule, 
        ReactiveFormsModule,
        DataTableModule,
        SharedModule,
        PopoverModule,
        PrimeNgDropDownModule,
        DropdownModule.forRoot(),
        CheckboxModule,
        InputTextModule,
        MenuModule
    ],
    });
    fixture = TestBed.createComponent(ManualProcessComponent);
    manualProcessService = TestBed.get(ManualProcessService);
    spyOn(manualProcessService, 'getManualProcessData').and.returnValue(Observable.of(MANUALPROCESSMOCKDATA));
    fixture.detectChanges();
  });

  it('Filters should be reset', (done) => {
    fixture.componentInstance.clearFilters()
    fixture.detectChanges();
    expect(fixture.componentInstance.filterBy.length).toBe(0);
    done();
  })

  it('Should load list of manual process files', fakeAsync(() => {
    fixture.componentInstance.loadData(event);
    tick();
    fixture.detectChanges();
    expect(fixture.componentInstance.filterBy.length).toBe(10);
  }));
});

我是Angular 2和单元测试的新手。有人能指导一下吗,我做错了什么。

9w11ddsr

9w11ddsr1#

我也遇到了这个问题,并将我的测试改为直接针对组件的ngOnInit()方法。

fixture.detectChanges();

你可以试试

fixture.componentInstance.ngOnInit();

(or无论生命周期钩子是组件的入口点)。这对我很有效。它使我免于测试失败,即使组件本身运行良好。

vhmi4jdf

vhmi4jdf2#

每次更改值时都应检测到更改,并且在赋值之前执行before Each,因此hi将获得错误。

fixture.detectChanges();

在你的it语句中,调用每一个值的变化。
更新1:

import { ManualProcessService } from '../../services/manual-process.service';
import { ManualProcessComponent } from './manual-process.component';
import { MANUALPROCESSMOCKDATA } from '../../shared/mocks/mock-manualprocessdata';
import { IManualProcessData } from '../../models/manual-process.model';
import {
    async,
    TestBed,
    fakeAsync,
    tick,
} from '@angular/core/testing';
// used to interact with the HTML elements 
import { By } from '@angular/platform-browser';

describe('Testing Manual Process Component', () => {

    let fixture,
        event = {
            first: 0,
            rows: 10
        },
        manualProcessService;
    let hardCodedData = {
        ...
    };
    beforeEach(async () => {
        TestBed.configureTestingModule({
            imports: [],
            declarations: [ManualProcessComponent],
            providers: [
                { provide: ManualProcessService, useValue: mockManualProcessService }
            ]
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(ManualProcessComponent);
        component = fixture.componentInstance;
        debugElement = fixture.debugElement;
        element = fixture.nativeElement;
        // analyse your component and the variables used in it and make hard values of them
        let variables;
        // Note: Never call detectChanges() inside a beforeEach
    })

    it('Filters should be reset', (done) => {
        fixture.componentInstance.clearFilters();
        fixture.detectChanges();
        expect(fixture.componentInstance.filterBy.length).toBe(0);
        done();
    })

    it('Should load list of manual process files', fakeAsync(() => {
        fixture.componentInstance.loadData(event);
        tick();
        fixture.detectChanges();
        expect(fixture.componentInstance.filterBy.length).toBe(10);
    }));

    it('a sample case to check if the text box contains expected value aor not',()=>{
        expect(debugElement.query(By.css('.className')).nativeElement.textContent).toBe('somename');
    });
});
qgzx9mmu

qgzx9mmu3#

经过以下更改后,它对我很有效
更改beforeEach

beforeEach(() => {
    ...
})

beforeEach(async () => {
    ...
})
b1payxdu

b1payxdu4#

对我来说,将以下内容添加到@Component配置中解决了我的问题:

@Component({
...
changeDetection: ChangeDetectionStrategy.OnPush
})
vq8itlhq

vq8itlhq5#

对于此类错误,请运行应用程序(ng serve)&
检查浏览器控制台,如果得到相同的错误
如果是这样的话,那就这样吧

core.mjs:6494 ERROR Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.. Find more at https://angular.io/errors/NG0100
at throwErrorIfNoChangesMode (core.mjs:6744:1)
at bindingUpdated (core.mjs:12747:1)
at ɵɵproperty (core.mjs:14480:1)
at TableComponent_td_10_Template (template.html:98:11)
at executeTemplate (core.mjs:9632:1)
at refreshView (core.mjs:9495:1)
at refreshEmbeddedViews (core.mjs:10646:1)
at refreshView (core.mjs:9519:1)
at refreshComponent (core.mjs:10692:1)
at refreshChildComponents (core.mjs:9291:1)

点击template.html,它将导航到模板中出现错误的行。相应地检查并更改数据。
这解决了我的问题

相关问题