简体   繁体   English

测试Angular组件时的Jasmine spyOn服务

[英]Jasmine spyOn service when testing Angular component

I'm trying to test my Angular component with Jasmine. 我正在尝试用Jasmine测试我的Angular组件。 The component is a simple form that submits some search criteria to a service which then goes off and does the Http stuff and returns an array of entities. 该组件是一种简单的表单,向服务提交一些搜索条件,然后该服务关闭并执行Http填充并返回实体数组。

I am using Jasmine to 'spyOn' the service method and then return a mock entity. 我正在使用Jasmine来'spyOn'服务方法,然后返回一个模拟实体。 This mock entity should then be saved in a variable in the component. 然后,应将此模拟实体保存在组件中的变量中。

The problem I am facing is that when I come to assert that the entity has been successfully returned, I am getting undefined in the entities variable which makes me think I haven't set up my spy correctly or something similar. 我面临的问题是,当我断言该实体已成功返回时,我在entities变量中变得未定义,这使我觉得我没有正确设置间谍程序或类似的东西。

Any help will be greatly appreciated! 任何帮助将不胜感激!

Service: 服务:

@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: 零件:

@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;
            });
    }

    ...
}

Test: 测试:

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`);
        }
    ));
});

It fails on the second expect because component.entities is undefined. 由于component.entities未定义,因此它在第二个期望值上失败。

You are working with Promise that is async code. 您正在使用异步代码Promise。 Put expect into fixture.whenStable func and add async function into 'it' unit test. 将Expect放入fixture.whenStable函数中,并将异步函数添加到“ it”单元测试中。

fixture.whenStable().then(() => {
    expect(component.entities).toBeDefined('no entities returned');
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM