Angular Karma Test,不确定如何测试XML响应并返回XML有一个解析错误

时间:2017-04-25 10:52:23

标签: xml unit-testing angular karma-jasmine angular2-services

我的Angular App(用TypeScript编写)中有一个简单的服务,它加载一个静态XML文件,然后返回一个格式化的XML Document,它看起来像这样......

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { WindowService } from '../window-service/window.service';

@Injectable()
export class DataService {

    private xmlHeaders: any = {
        Accept: 'application/xml',
        'Content-Type': 'application/xml'
    };

    constructor(private windowService: WindowService, private http: Http) {
    }

    getXML(): Observable<any> {

        return this.http.get('/assets/data/data.xml', {
            headers: this.xmlHeaders
        }).map((response) => this.parseXML(response.text()));

    }

    parseXML(rawText): any {

        const window = this.windowService.getWindow();

        if (typeof (<any>window).DOMParser !== 'undefined') {

            return (new (<any>window).DOMParser()).parseFromString(rawText, 'text/xml');

        } else if (typeof (<any>window).ActiveXObject !== 'undefined' && new (<any>window).ActiveXObject('Microsoft.XMLDOM')) {

            const xmlDoc = new (<any>window).ActiveXObject('Microsoft.XMLDOM');
            xmlDoc.async = 'false';
            xmlDoc.loadXML(rawText);
            return xmlDoc;

        } else {
            throw new Error('Yikes! There\'s no XML Parser!!!');
        }
    }
}

现在我已经为我的服务编写了一个测试文件,看起来就是这样......

import { async, TestBed, inject } from '@angular/core/testing';
import { ResponseOptions, BaseRequestOptions, Http, Response, XHRBackend } from '@angular/http';
import { MockBackend, MockConnection} from '@angular/http/testing';
import { assertThat, is, truthy, hasProperties, contains} from 'hamjest';
import { SinonStub, stub} from 'sinon'
import { wasCalled } from '../test/matcher/wasCalled';
import { returnXMLdoc} from '../test/data-functions/mockXML';
import { WindowService } from '../window-service/window.service';
import { DataService } from './data.service';

describe('DataService', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                DataService,
                MockBackend,
                BaseRequestOptions,
                WindowService, // ToDo: Mock this,
                {
                    provide: Http,
                    deps: [MockBackend, BaseRequestOptions],
                    useFactory: (backendInstance: XHRBackend, defaultOptions: BaseRequestOptions) => {
                        return new Http(backendInstance, defaultOptions);
                    }
                }
            ]
        });
    });

    let sut: DataService;
    let backend: MockBackend;

    beforeEach(inject([
        DataService, MockBackend
    ], (dataService: DataService, mockBackend: MockBackend) => {
        sut = dataService;
        backend = mockBackend;
    }));

    it('should create an instance', () => {

        assertThat(sut, is(truthy()));
    });

    describe('getXML()', () => {

        it('should call backend with headers', async(() => {
            const assertionCall: SinonStub = stub();
            backend.connections.subscribe((connection: MockConnection) => {
                assertThat(connection.request.headers.toJSON().Accept, contains('application/xml')
                );
                assertionCall();
            });
            sut.getXML();

            assertThat(assertionCall, wasCalled());
        }));

        xit('should return XML data', async(() => {

            const assertionCall: SinonStub = stub();
            backend.connections.subscribe((connection: MockConnection) => {
                connection.mockRespond(new Response(returnXMLdoc(null)));
            });

            sut.getXML().subscribe((response) => {
                // toTo: put test here...

                // also if I console.log(response) there is a parsing error!
                assertionCall();
            });

            assertThat(assertionCall, wasCalled());
        }));

    });
});

问题是......(我对测试不是很好)是因为我不确定如何测试返回的内容?我也注意到在第二次测试中,当我尝试输出内容时,XML有格式错误。

这是控制台日志:

文档

<html><body><parsererror xmlns="http://www.w3.org/1999/xhtml" style="display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"><h3>This page contains the following errors:</h3><div style="font-family:monospace;font-size:12px">error on line 1 at column 1: Extra content at the end of the document
</div><h3>Below is a rendering of the page up to the first error.</h3></parsererror></body></html>

您会注意到returnXMLdoc(null)函数用于模拟数据,这是import { returnXMLdoc } from '../test/data-functions/mockXML';的内容返回的数据(XML文档)与静态内容相同文件我在我的服务中发出了一个http请求。

export function returnXMLdoc(selector) {

    const rawText = `<?xml version="1.0" encoding="UTF-8"?>
        <package>
          <level id="l1">
            <unit id="u1">
              <activity id="a1"></activity>
              <activity id="a2"></activity>
            </unit>
            <unit id="u2">
              <activity id="a3"></activity>
            </unit>
          </level>
          <level id="l2">
            <unit id="u3">
              <activity id="a4"></activity>
            </unit>
          </level>
        </package>`;

    const xmlDoc = (new (<any>window).DOMParser()).parseFromString(rawText, 'text/xml');

    if (selector) {
        return xmlDoc.getElementsByTagName(selector);
    }

    return xmlDoc;
}

有人可以就如何测试getXML服务及其返回的内容向我提供建议。非常感谢提前。

1 个答案:

答案 0 :(得分:0)

不确定你要在这里完成什么

connection.mockRespond(new Response(returnXMLdoc(null)));

您应该将ResponseOptions传递给Response构造函数。使用ResponseOptions,您可以设置所需的所有值

const options = new ResponseOptions({
  body: `<raw>XML</raw>`,
  status: 200,
  headers: new Header({
    'content-type': 'application/xml'
  })
})
new Response(options);

当您在客户端呼叫response.text()时,您将获得原始身体<raw>XML</raw>