【问题标题】:jasmine, karma, Expected 0 to be 1, 'found in tabs found'茉莉,业力,预期 0 为 1,'在找到的标签中找到'
【发布时间】:2020-12-29 19:56:11
【问题描述】:

我尝试使用大量课程来测试一个组件。所以我尝试做一个单元测试,有超过 0 门课程可用。所以我有这个:

it('should display only beginner courses', () => {

    courseServiceSpy.findAllCourses.and.returnValue(of(beginnerCourses));

    fixture.detectChanges();

    const tabs = el.queryAll(By.css('.mat-tab-label'));

    expect(tabs.length).toBe(1, 'found in tabs found');
  });

这是模板:

  <ng-container *ngIf="(beginnerCourses$ | async) as beginnerCourses">

        <mat-tab label="Beginners" *ngIf="beginnerCourses?.length > 0">

          <courses-card-list (courseEdited)="reloadCourses()"
                             [courses]="beginnerCourses">

          </courses-card-list>

        </mat-tab>

      </ng-container>

但我仍然收到此错误:

Expected 0 to be 1, 'found in tabs found'.
Error: Expected 0 to be 1, 'found in tabs found'.
    at <Jasmine>
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/courses/home/home.component.spec.ts:60:25)
    at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:364:1)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/proxy.js:117:1)

那么我要改变什么?

谢谢

这是我的全部课程:

describe('HomeComponent', () => {
  let fixture: ComponentFixture<HomeComponent>;
  let component: HomeComponent;
  let el: DebugElement;
  let courseServiceSpy: SpyObj<CoursesService>; // Declare the spy here

  const beginnerCourses = setupCourses().filter(course => course.category === 'BEGINNER');
  const advancedCourses = setupCourses().filter(course => course.category === 'ADVANCED');

  beforeEach(async(() => {
    // Initialize the spy here
    courseServiceSpy = jasmine.createSpyObj('CoursesService', [
      'findAllCourses',
    ]);

    TestBed.configureTestingModule({
      imports: [CoursesModule, HttpClientTestingModule, NoopAnimationsModule],
      providers: [{provide: CoursesService, usevalue: courseServiceSpy}],
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(HomeComponent);
        component = fixture.componentInstance;
        el = fixture.debugElement;
      });
  }));

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

  it('should display only beginner courses', () => {

    courseServiceSpy.findAllCourses.and.returnValue(of(beginnerCourses));

    fixture.detectChanges();

    const tabs = el.queryAll(By.css('.mat-tab-label'));

    expect(tabs.length).toBe(1, 'found in tabs found');
  });

  it('should display only advanced courses', () => {
    courseServiceSpy.findAllCourses.and.returnValue(of(advancedCourses));

    fixture.detectChanges();

    const tabs = el.queryAll(By.css('.mat-tab-label'));

    expect(tabs.length).toBe(1, 'found in tabs found');
  });

});

这就是方法:

  findAllCourses(): Observable<Course[]> {
        return this.http.get('/api/courses')
            .pipe(
                map(res => res['payload']), shareReplay()
            );
    }

【问题讨论】:

标签: javascript angular unit-testing karma-jasmine


【解决方案1】:

间谍只模拟一个动作,但并不真正作用于你的组件。 您需要模拟您的服务以返回of(beginnerCourses)

创建一个模拟类:

class CourseServiceMock {
  findAllCourses() {
    return of(beginnerCourses);
  }
}

并将其声明为提供者使用的类(并删除您的间谍):

TestBed.configureTestingModule({
      imports: [CoursesModule, HttpClientTestingModule, NoopAnimationsModule],
      providers: [{provide: CoursesService, usevalue: CourseServiceMock}],
    })

【讨论】:

  • 当然谢谢。但我已经有了一个模拟: let courseServiceSpy: SpyObj; // 在此处声明 spy: courseServiceSpy = jasmine.createSpyObj('CoursesService', [ 'findAllCourses', ]);
  • and toBe 接受两个参数:toBe(expected: Expected, expectFailOutput?: any): boolean;
  • 间谍不是模拟物:有两种不同的东西。模拟的目标是为您的测试环境提供自定义类而不是调用外部依赖项(并避免在您的情况下进行 http 调用)。间谍的目标是观察其他动作,而不是真正触发动作本身。
  • 嗯,为了模拟一些东西,你正在使用 jasmine.spy:见:codecraft.tv/courses/angular/unit-testing/mocks-and-spies。但我当然感谢你的热情。非常感谢你的帮忙。但我以正确的方式解决了。祝你有美好的一天
  • @Grignon。看我的回答。所以你可以从中学到一些东西:)
【解决方案2】:

我解决了, 这行得通:

import { filter } from 'rxjs/operators';
import {setupCourses} from '../common/setup-test-data';
import {
  async,
  ComponentFixture,
  TestBed,
} from '@angular/core/testing';
import { CoursesModule } from '../courses.module';
import { DebugElement } from '@angular/core';

import { HomeComponent } from './home.component';
import {
  HttpClientTestingModule,
} from '@angular/common/http/testing';
import { CoursesService } from '../services/courses.service';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { of } from 'rxjs';
import SpyObj = jasmine.SpyObj;
import { By } from '@angular/platform-browser';

describe('HomeComponent', () => {
  let fixture: ComponentFixture<HomeComponent>;
  let component: HomeComponent;
  let el: DebugElement;
  let coursesService: any;

  const beginnerCourses = setupCourses().filter(course => course.category === 'BEGINNER');
  const advancedCourses = setupCourses().filter(course => course.category === 'ADVANCED');

  beforeEach(async(() => {

    const coursesServiceSpy = jasmine.createSpyObj('CoursesService', ['findAllCourses']);

    TestBed.configureTestingModule({
        imports: [
            CoursesModule,
            NoopAnimationsModule
        ],
        providers: [
            {provide: CoursesService, useValue: coursesServiceSpy}
        ]
    }).compileComponents()
        .then(() => {
            fixture = TestBed.createComponent(HomeComponent);
            component = fixture.componentInstance;
            el = fixture.debugElement;
            coursesService = TestBed.inject(CoursesService);
        });

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

  it('should display only beginner courses', () => {

    coursesService.findAllCourses.and.returnValue(of(beginnerCourses));

    fixture.detectChanges();

    const tabs = el.queryAll(By.css('.mat-tab-label'));

    expect(tabs.length).toBe(1);
  });

  it('should display only advanced courses', () => {
    coursesService.findAllCourses.and.returnValue(of(advancedCourses));

    fixture.detectChanges();

    const tabs = el.queryAll(By.css('.mat-tab-label'));

    expect(tabs.length).toBe(1, 'found in tabs found');
  });

  it('should display both tabs', () => {
    pending();
  }); 
});

所以这个:

 const coursesServiceSpy = jasmine.createSpyObj('CoursesService', [
      'findAllCourses',
    ]);

正在创建模拟。所以不一定要单独的mock

【讨论】:

    猜你喜欢
    • 2015-12-27
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 2020-05-21
    • 1970-01-01
    • 2020-05-11
    相关资源
    最近更新 更多