运行测试后销毁App组件

时间:2018-02-26 10:56:08

标签: angular unit-testing jasmine karma-jasmine

我正在开发一个有角度的网站,我在运行单元测试时遇到了问题。我有我的app组件

export class Appcomponent {
    constructor(private service: SomeService) {
        service.init()
    }
}

并且服务的init()方法有

init() {
    setInterval(() => {
        this.http.get(' /api/configuration/v1/log').map(res=> res).subscribe(() => {});
    }, 30000)
}

现在的问题是,当我运行这样的单元测试时,

describe('Appapponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let app: AppComponent;

  beforeEach(() => {
    TestBed.configureTestingModule(
      {
        declarations: APP_DECLARATIONS,
        imports: APP_IMPORTS,
        providers: [APP_PROVIDERS, { provide: APP_BASE_HREF, useValue: '/' }]
      }
    ).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    app = fixture.debugElement.componentInstance;
    fixture.detectChanges();
  });

  it('should create the app', () => {
    expect(app).toBeDefined();
  });
});

当我运行测试时,测试运行正常但http调用因设置间隔而继续运行,测试不会退出。如下图所示

enter image description here

因此,构建会超时并失败。如何解决这个问题?请帮我。

修改

添加了COnfivguration

module.exports = function(config) {
    config.set({
        basePath: '',
        frameworks: ['jasmine', '@angular/cli'],
        plugins: [
            require('karma-jasmine'),
            require('karma-phantomjs-launcher'),
            require('karma-chrome-launcher'),
            require('karma-junit-reporter'),
            require('karma-jasmine-html-reporter'),
            require('karma-coverage-istanbul-reporter'),
            require('@angular/cli/plugins/karma')
        ],
        client: {
            clearContext: false
        },
        files: [
            { pattern: './src/test.ts', watched: false }
        ],
        preprocessors: {
            './src/test.ts': ['@angular/cli']
        },
        coverageIstanbulReporter: {
            reports: ['html', 'lcovonly'],
            fixWebpackSourcePaths: true
        },
        angularCli: {
            environment: 'dev'
        },
        mime: {
            'text/x-typescript': ['ts']
        },
        reporters: ['progress', 'kjhtml'],
        port: 9876,
        colors: true,
        logLevel: config.LOG_INFO,
        autoWatch: true,
        mime: { 'text/x-typescript': ['ts', 'tsx'] },
        browsers: ['PhantomJS'],
        singleRun: false,
        captureTimeout: 200000,
        browserDisconnectTimeout: 2000,
        browserDisconnectTolerance: 3,
        browserNoActivityTimeout: 200000
    });
};

1 个答案:

答案 0 :(得分:2)

我想知道的

 this.http.get(' /api/configuration/v1/log').map(res=> res).subscribe(() => {});

您为什么使用该代码以及它的用途。我认为代码什么都不做。请确保此代码真的是您的应用程序???。

问题

  

但不管怎么说。为什么在$http内使用controller.component服务电话?它应该写在service.componenet部分的内部。因为那时只有你可以在单元测试时编写mock service而不是实际服务。

那么,你想在UI单元测试中做什么

您应该将此$http电话转移到服务类,例如

export class SomeService{
    constructor(private http: $http) {

    }    
   get()
    {
      setInterval(() => {
      this.http.get(' /api/configuration/v1/log').map(res=> 
      res).subscribe(() => {});
    }, 30000)
  }
}
  • 然后您应该使用get()中的模拟数据返回相同的Mock Service class方法。

    export class MockSomeService{
    constructor(private http: $http) {            
    }    
    get()
    {
     return Observable.of({});   //{} send mock data which you want to be check          
    }
 }
  • 在配置测试组件时,通过提供程序传递模拟类而不是真正的类。

providers: [{ provide: SomeService, useClass: MockSomeService}]
  

现在真正的服务在测试时被嘲笑了。因此,您可以获取模拟数据而不是real data/real service call来检查测试用例期望。

SetTimout()问题的解决方案

通常,如果您在Settimeout()中使用controller.componenet功能。您需要在测试用例中的fixture.detectChanges();旁边添加以下代码行。

        tick(3000);
        fixture.whenStable().then(() => {
            expect(0).toEqual(0);// do your expectation 
        });