我试图用茉莉花测试我的角组件。该组件是一个简单的表单,它将一些搜索条件提交给一个服务,该服务然后会关闭并执行Http的东西并返回一组实体。茉莉花spyOn服务时测试角组件
我正在使用Jasmine'spyOn'服务方法,然后返回一个模拟实体。这个模拟实体应该保存在组件中的一个变量中。
我面临的问题是,当我断言实体已成功返回时,我在实体变量中得到了未定义,这使我认为我没有正确设置我的间谍或类似的东西。
任何帮助将不胜感激!
服务:
@Injectable()
export class DynamicsSearchService {
private apiUrl = '/api/DynamicsSearch/Search';
private headers = new Headers({ 'Content-Type': 'application/json' });
constructor(private http: Http) { }
search(search: DynamicsSearch): Promise<any[]> {
search.fields = this.getDefaultFields(search.entity);
return this.http
.post(this.apiUrl, JSON.stringify(search), { headers: this.headers })
.toPromise()
.then((response) => { return this.extractResults(search.entity, response.json()); })
.catch(this.handleError);
}
...
}
组件:
@Component({
selector: 'dynamics-search-component',
templateUrl: 'dynamics-search.component.html'
})
export class DynamicsSearchComponent {
...
entities: any[];
constructor(private searchService: DynamicsSearchService) { }
submitSearch() {
this.searching = this.searched = true;
this.searchService.search(this.model)
.then(results => {
this.entities = results;
this.searching = false;
this.searchSuccessful = results !== null && results.length > 0;
});
}
...
}
测试:
describe('DynamicsSearchComponent',() => {
let fixture: ComponentFixture<DynamicsSearchComponent>;
let component: DynamicsSearchComponent;
let configuration = new Configuration();
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
SharedModule
],
providers: [
BaseRequestOptions,
MockBackend,
DynamicsSearchService,
Configuration,
{
provide: Http,
useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
},
deps: [
MockBackend,
BaseRequestOptions
]
}
],
declarations: [
DynamicsSearchComponent
]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DynamicsSearchComponent);
component = fixture.componentInstance;
});
it('on submit should get a single contact',
inject([DynamicsSearchService], (service: DynamicsSearchService) => {
var expected = [
{
contactid: 'A7806F57-002C-403F-9D3B-89778144D3E1'
}
];
const spy = spyOn(service, 'search')
.and.returnValue(Promise.resolve(expected));
component.model = new DynamicsSearch('contacts', 'A7806F57-002C-403F-9D3B-89778144D3E1', null, 'contactid');
component.submitSearch();
fixture.detectChanges();
expect(spy.calls.count()).toBe(1, `expected service search method to be called once but was called ${spy.calls.count()} times`);
expect(component.entities).toBeDefined('no entities returned');
expect(component.entities.length).toBe(1, `expected 1 entity to be returned but only ${component.entities.length} were returned`);
}
));
});
它未能在第二期待,因为component.entities
是不确定的。
你应该把它分成两个单独的测试 - 这是一个非常糟糕的迹象,你拉'Http来测试组件。用'MockBackend'测试服务,然后用假服务测试组件。此外,您可能需要'fixture.detectChanges()'以确保服务数据返回后所有内容都会更新。 – jonrsharpe
谢谢乔恩。我承担这一点,就是前进,并尝试重构服务位一次/如果我能找出这个问题。提交搜索后,还添加了一个'fixture.detectChanges()',这似乎没有帮助。上面更新。 –
我的观点是,这将帮助你*现在*来隔离问题并创建一个[mcve]。我最近在一些同事的博客上写了一些我们的服务和组件测试,可能有用:http://blog.jonrshar.pe/2017/Apr/16/async-angular-tests.html – jonrsharpe