2017-05-08 83 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。現在它的作用得益於您的輸入。 –