2017-05-08 74 views
1

我正在处理Angular 4上的大型项目。我们从服务器获取JSON数据,然后在客户端的特殊表格组件中显示该数据。在Jasmine测试之前加载配置

表的特点是,您可以定义客户端列显示。要找出哪些列,我们从服务器获取一个配置JSON文件。而且因为我们在模块加载之前只需要这个东西,所以我把加载机制放在了一个警卫之中。到目前为止,这工作正常。

我有2个要求:

  • 获取列声明中后卫
  • 从服务器获取数据,并填写表格。这是在组件

现在我也必须测试这一点。这就是我的麻烦开始的地方。在jasmine执行单元测试之前,我无法获得列JSON请求。

fdescribe('Component: MyComponent',() => { 
    let fixture: ComponentFixture<MyComponent>; 
    let component: MyComponent; 

    beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ 
     MyComponent 
     ], 
     providers: [ 
     FieldConfigurationService 
     ], 
     schemas: [NO_ERRORS_SCHEMA], 
     imports: [ 
     TranslateModule.forRoot({ 
      provide: TranslateLoader, 
      useFactory: (http: Http) => new TranslateStaticLoader(http, 'resources/i18n', '.json'), 
      deps: [Http] 
     }) 
     ] 
    }).overrideComponent(MyComponent, { 
     set: { 
     providers: [] 
     } 
    }).compileComponents() 
     .then(() => { 
     fixture = TestBed.createComponent(MyComponent); 
     component = fixture.componentInstance; 
     }); 
    })); 

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

    describe('when field Configuration is loaded',() => { 
    beforeEach(async(() => { 
     console.log(1); 
     component.fieldConfigurationService.loadConfiguration(true); 
     console.log(2); 
    })); 

    describe('when the component is ready for use',() => { 
     console.log(3); 
    }); 
    }); 
}); 

console.log的输出是3,1,2。

我该如何放置component.fieldConfigurationService.loadConfiguration();命令,以便在console.log(3)块启动之前执行该事件。

我也试图在测试平台的“然后”部分插入它。无论我迄今为止做了什么,由于数据加载过程的异步特性,在从服务器加载数据之前总是开始执行单元测试。

任何帮助是非常感激。

FieldConfigurationService看起来像这样。

@Injectable() 
export class FieldConfigurationService { 
    public config: any = {}; 
    public loadConfiguration(isUnitTest: boolean = false): Promise<any> { 
     return new Promise((resolve, reject) => { 
      if (isUnitTest) { 
      if (!this.config) { 
       this.config = this.readJSON('base/gulpdist/field-definition.json'); 
       resolve(this.config); 
      } else { 
       resolve(null); 
      } 
      } else { 
      if (!this.config) { 
       this.getJSON().subscribe(
       data => { 
        this.config = data; 
        resolve(data); 
       }, 
       error => reject(error) 
      ); 
      } else { 
       resolve(null); 
      } 
      } 
     }); 
    } 
    } 

    private readJSON(url) { 
     let xhr = new XMLHttpRequest(); 
     let json = null; 

     xhr.open('GET', url, false); 

     xhr.onload = function (e) { 
     if (xhr.status === 200) { 
      json = JSON.parse(xhr.responseText); 
     } else { 
      console.error('readJSON', url, xhr.statusText); 
     } 
     }; 

     xhr.onerror = function (e) { 
     console.error('readJSON', url, xhr.statusText); 
     }; 

     xhr.send(null); 
     return json; 
    } 
} 

非常感谢您 西蒙

回答

1

首先,这是一个坏主意

public loadConfiguration(isUnitTest: boolean = false): Promise<any> { 
    return new Promise((resolve, reject) => { 
     if (isUnitTest) { 

单元测试不应该泄漏到您的实现细节是这样的。 应该所做的只是模拟配置数据。

import { mockConfigData } from './whereever'; 

... 
const config = new FieldConfigurationService(); 
config.config = mockConfigData; 

providers: [ 
    { provide: FieldConfigurationService, useValue: config } 
] 

因此,您已经设置了服务以使用模拟文件可能来自哪里的一些模拟数据。现在,你需要做的是解决resolve(null)

if (!this.config) { 
    ... 
} else { 
    resolve(null); 
} 

什么是解决null点。这个逻辑的整点是“如果没有配置,取回它,否则返回空???”。不应该是“否则返回配置”?所以解决。使其解决配置

if (!this.config) { 
    ... 
} else { 
    resolve(this.config); 
} 

这样,承诺解决同步,这样你就不需要用测试来改变任何东西,除非你删除isUnitTest废话,我会强烈建议你这样做。

+0

哈哈哈哈...谢谢。我非常关注单元测试,完全忽略了FieldConfigurationService。现在它的作用得益于您的输入。 –

相关问题