【问题标题】:Unable to test the dynamic content using Karma-jasmine testing tool in angular 6 project无法在 Angular 6 项目中使用 Karma-jasmine 测试工具测试动态内容
【发布时间】:2018-11-08 13:14:01
【问题描述】:

在 Angular 6 中为动态内容编写测试用例时需要帮助,以及 使用 Karma 包。

spec.ts:

我写了测试用例来检查文章的观点。前 执行该函数,它正在传递,但在获取数据后它是 不通过。如何为动态内容编写测试用例。

describe('SingleArticleVideoComponent', () => {
    let originalTimeout;
  let debugTest: DebugElement[];
  let el: HTMLElement;
  let component: SingleArticleVideoComponent;
  let fixture: ComponentFixture<SingleArticleVideoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SingleArticleVideoComponent,
          PollsComponent,
          AdBannerComponent],
        imports: [
            RouterTestingModule,
            NavModule,
        FooterModule,
            VgCoreModule,
            VgControlsModule,
            VgOverlayPlayModule,
            VgBufferingModule,
        FormsModule,
        ReactiveFormsModule,
        MatFormFieldModule,
        MatRadioModule,
        MatDialogModule,
            HttpModule,
            HttpClientModule,
            BrowserAnimationsModule,
            BrowserModule
        ],
        providers: [
            ArticleService,
            AdService,
            UserServiceService
        ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SingleArticleVideoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
      originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
      jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
  });
    afterEach(function() {
        jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
        fixture = TestBed.createComponent(SingleArticleVideoComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });
    it('views should be more than 100', async(() => {
        expect(component.anchor).toEqual('before');
        expect(component.anchor).toEqual('after');
    }));
  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

component.ts:

当我使用 ng serve 时,它给出了正确的结果,但它不是 使用 ng test 进行测试。

ngOnInit() {
     this.get_single_video('emcure-csi-tv-dr-pk-dep-ACE-inhibitor-or-ARNI-what-should-be-used-in-heart-failure-with-reduced-ejection-fraction', this.category);
}
get_single_video(slug, category) {
    console.log('get one video calling');
    this.anchor ='before';
    this.service.get_single_video(slug, category).subscribe(
      data => {
        if(data['success'])
        {
            this.anchor='after';
          this.load_data = true;
            if(data['data']['guest3'].length > 0 || data['data']['guest4'].length > 0){
                this.gus = true;
            }
        }
});

component.html:

当我控制台它时,Views 给出了 null。视图正常显示 如果我使用 ng serve 运行它,而不是 ng test

<li class="views"><code>{{single_article['anchor']}}</code><br>Views</li>

user-service.service.ts:

我可以在 map 函数中看到 data.json(),但我无法获取 正如我提到的,在 component.ts 文件中的 subscribe 函数中 以上。

import 'rxjs/Rx';
get_single_video(slug, catagory) {
    console.log('in article service single video');
    const final_url = this.api_url + '/' + slug + '?key=' + this.api_key;
    console.log(final_url);
    return this._http.get(final_url)
      .map(data => {
        data.json();
        // the console.log(...) line prevents your code from working
        // either remove it or add the line below (return ...)
        console.log(' I CAN SEE DATA HERE: ', data.json());
        return data.json();
      }).catch(error => observableThrowError(error.json()));
  }

【问题讨论】:

  • 我在下面的回答有帮助吗?

标签: angular unit-testing jasmine karma-jasmine karma-runner


【解决方案1】:

您通常不希望您的单元测试对后端进行 http 调用,而是模拟该功能。事实上,在组件测试中,您甚至想模拟服务的功能(因此即使服务搞砸了组件单元测试也可以通过)。有关“ng test”和“ng e2e”之间区别的良好解释,请参阅以下问题的公认答案:question

假设您想在此阶段进行单元测试,并且只是对组件进行测试,那么我将设置一个间谍来模拟您的服务调用并返回各种值,以便您可以通过“get_single_video”组件方法的逻辑进行测试.我已经设置了一个STACKBLITZ 来使用您自己的问题代码来演示这一点。我设置了最少量的代码来说明我的意思。 (MCVE)

需要注意的一点 - 我将 fixture.detectChanges() 从 beforeEach() 中提取出来,并将其放入 'it' 函数中。这是因为fixture.detectChanges() 调用 ngOnInit(),并且需要在调用 ngOnInit() 之前设置服务调用的返回值,以便您可以通过逻辑控制路径。

从那次堆栈闪电战中,这是我为测试两条路径而设置的描述。您应该能够扩展它以完全覆盖您的功能。

describe('SingleArticleVideoComponent', () => {
    let component: SingleArticleVideoComponent;
    let fixture: ComponentFixture<SingleArticleVideoComponent>;
    let userServiceSpy = jasmine.createSpyObj('UserServiceService', ['get_single_video']);

    beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [ SingleArticleVideoComponent],
            providers: [
                { provide: UserServiceService, useValue: userServiceSpy }
            ]
        })
        .compileComponents();
    }));
    beforeEach(() => {
        fixture = TestBed.createComponent(SingleArticleVideoComponent);
        component = fixture.componentInstance;
    });

    it('should change anchor to "after" if get_single_video() has success set', () => {
        userServiceSpy.get_single_video.and.returnValue(of({success: 'yes', data: {guest3: ['1']}}));
        fixture.detectChanges();
        expect(component.anchor).toEqual('after');
    });
    it('should not change anchor if get_single_video() does not have success set', () => {
        userServiceSpy.get_single_video.and.returnValue(of({})); // Observable of an empty object
        fixture.detectChanges();
        expect(component.anchor).toEqual('before');
    });
});

【讨论】:

    【解决方案2】:

    不要测试 API 调用,它是单元测试中的数据。回到组件,将fixture.detectChanges();beforeEach 取出到it 将提供对数据流的控制。 您可以添加模拟服务,

    providers: [{ provide: UserServiceService, useValue: userServiceSpy }]
    

    确保您在userServiceSpy 服务间谍中有get_single_video,它返回Observable 类型的数据。

    beforeEach 方法上,通过在其中传递模拟服务来初始化组件。例如

    videoComponent = new SingleArticleVideoComponent(userServiceSpy)
    

    您可以将此 videoComponent 用于您的测试用例。

    【讨论】:

      猜你喜欢
      • 2014-11-15
      • 2015-12-07
      • 1970-01-01
      • 2018-10-25
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 2018-01-31
      • 2014-09-20
      相关资源
      最近更新 更多