Angular 2 with jasmine:测试组件,注入服务

时间:2016-11-01 11:08:08

标签: javascript unit-testing angular typescript jasmine

我无法为我的Angular 2项目创建一个简单的茉莉花测试。这就是我想要做的事情:

要测试的组件(基于服务):

@Component({
    providers: [AccountService],
    selector: "account",
    templateUrl: "app/account/account.component.html",
})

export class AccountComponent implements OnInit {

    public accounts: Account[];    
    public error: string;

    constructor(private accountService: AccountService) {}

    public ngOnInit(): any {
        this.getAccounts();
    }

    public getAccounts() {
        this.accountService.getAccounts()
            .then(
                accounts => this.accounts = accounts,
                error => this.error = error
            );
    }
}

AccountService使用Http(来自@angular/http); getAccounts方法返回一个带有(希望)帐户列表的承诺。

我正在尝试使用假AccountComponent(模拟)测试AccountService。基于https://www.freemysqlhosting.net/,以下是我的spec文件的实现:

describe('Account module test', () => {    
    let accountServiceMock;
    let fixture;
    let comp;
    let spy;

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ AccountComponent ],
            providers:    [ AccountService ],
        });

        fixture = TestBed.createComponent(AccountComponent);
        comp    = fixture.componentInstance;

        // AccountService actually injected into the component
        accountServiceMock = fixture.debugElement.injector.get(AccountService);

        // Setup spy on the `getAccounts` method; return no account (basic test)
        spy = spyOn(AccountService, 'getAccounts')
            .and.returnValue(Promise.resolve([]));

    });

    it('Should get 0 account', () => {

        comp.ngOnInit();    
        expect(comp.accounts.length).toBe(0);
    });
});

但它不起作用,我在终端中收到了一条非常难看的错误信息:

**stuff**/node_modules/@angular/core/bundles/core.umd.js:334
                var parameters = Reflect.getMetadata('parameters', cls) || [];

TypeError: Cannot read property 'getMetadata' of undefined
    at ParamDecorator (**stuff**/node_modules/@angular/core/bundles/core.umd.js:334:41)
    at __decorate (**stuff**/dist/js/app/account/account.service.js:5:95)
    at **stuff**/dist/js/app/account/account.service.js:86:22
    at Object.<anonymous> (**stuff**/dist/js/app/account/account.service.js:91:2)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)

知道我缺少什么吗?无法弄清楚如何解决这个问题......提前谢谢!

修改 基于评论,我尝试了另一种方式:

describe('component: AccountComponent', () => {
    let fixture;
    let service;

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [
                AccountComponent
            ],
        });

        fixture = TestBed.createComponent(AccountComponent);
        service = fixture.debugElement.injector.get(AccountService);
    });

    it('should get 0 account', () => {
        spyOn(service, 'getAccounts').and.returnValue([]);
        fixture.detectChanges();
        expect(fixture.componentInstance.accounts).toBe([]);
    });
});

我得到了完全相同的错误...我虽然在测试文件之外存在问题,但是当我删除beforeEach关闭并添加虚拟测试时,jasmine命令只运行精细。回到原点,我想:/

EDIT2:根据要求,这是我的AccountService类:

import {Http, Response, Headers} from "@angular/http";
import {Injectable} from "@angular/core";
import "rxjs/add/operator/toPromise";

export interface IAccountService {
    getAccounts();
}

@Injectable()
export class AccountService implements IAccountService {

    private static BASE_URL: string = "/api/account/";

    private static extractResult(res: Response) {
        return res.json();
    }

    /**
     * Extract error message from server response
     */
    private static handleError(error: any) {
        const errMsg: string = error._body;
        console.error(error); // log to console
        return Promise.reject(errMsg);
    }

    constructor(private http: Http) {
    }

    /**
     * Get list of accounts from server
     */
    public getAccounts() {
        return this.http.get(AccountService.BASE_URL)
            .toPromise()
            .then(AccountService.extractResult)
            .catch(AccountService.handleError);
    }
}

0 个答案:

没有答案