2016-08-18 72 views
0

我正在使用angular2 RC 5,我寫了一個自定義管道,它從json中獲取值。自定義管:literal.pipe.ts樣子:Angular 2 rc5,使用注入管道的單元測試問題

import {Pipe, PipeTransform, Inject} from '@angular/core'; 
import {MessageService} from '../service/message.service'; 

@Pipe({ 
    name: 'literalString', 
    pure: false 
}) 
export class LiteralPipe implements PipeTransform{ 

private messageBundle:any; 
private request:any; 

    constructor(private _messageService: MessageService){ 
     this._messageService = _messageService; 
     this.messageBundle = {}; 
    } 

    transform(value:string, args:string[]):any { 
     if(!this.request){ 
      this.request = this._messageService.getBundle(); 
      this.request.subscribe(
       (data:any) => this.messageBundle = data 
      ); 
     } 

     if(this.messageBundle[value]) 
      return this.messageBundle[value]; 
     else if(args[0]) 
      return args; 
     else 
      return "String not available. Pls include in bundle.json"; 
    } 
} 

MessageService.ts:

import {Injectable} from "@angular/core" 
import {Http} from '@angular/http'; 
import 'rxjs/Rx' 

@Injectable() 
export class MessageService{ 
    http:any; 
    constructor(http: Http){ 
     this.http = http; 
    } 
    getBundle(){ 
     return this.http.get('../src/bundle.json').map((res:any) => res.json()); 
    } 
} 

Bundle.json具有鍵值對作爲

{ 
      "Home.title": "Login", 
      "DashBoard.Title": "Dashboard", 
      "CheckOutGiftCard.Title": "GIFT CARD CHECKOUT" 
} 

我正在我的單位使用liteServer進行測試。我unitTests.html:

<meta http-equiv="content-type" content="text/html;charset=utf-8"> 
    <title>Ng App Unit Tests</title> 
    <link rel="stylesheet" href="../node_modules/jasmine-core/lib/jasmine-core/jasmine.css"> 
    <script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script> 
    <script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script> 
    <script src="../node_modules/jasmine-core/lib/jasmine-core/boot.js"></script> 
    <script src="node_modules/zone.js/dist/zone.js"></script> 

  <script src="node_modules/reflect-metadata/Reflect.js"></script> 

  <script src="node_modules/systemjs/dist/system.src.js"></script> 

  <script src="systemjs.config.js"></script> 
</head> 
<body> 
    <!-- Unit Testing Chapter #1: Proof of life. --> 
    <script> 
    it('true is true', function(){ expect(true).toEqual(true); }); 
    </script> 
    <script> 
    // #2. Configure systemjs to use the .js extension 
    //  for imports from the app folder 
    System.config({defaultJSExtensions:true}); 
    // #3. Load and configure the TestComponentBuilder. 
    // #2. Import the spec files explicitly 
    Promise.all([ 
     System.import('app/literal.pipe.spec') 
    ]) 
    // #3. wait for all imports to load ... 
    //  then re-execute `window.onload` which 
    //  triggers the Jasmine test-runner start 
    //  or explain what went wrong. 
    //System.import('app/literal.pipe.spec') 
    .then(window.onload) 
    .catch(console.error.bind(console)); 
    </script> 
</body> 
</html> 

literal.pipe.spec.ts如下:

import { By }    from '@angular/platform-browser'; 
import { provide }  from '@angular/core'; 
import { ViewMetadata } from '@angular/core'; 
import {LiteralPipe} from '../pipe/literal.pipe'; 
import {MessageService} from '../service/message.service'; 
import {Http} from '@angular/http'; 
import { TestBed } from '@angular/core/testing'; 
//import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; 

// TestBed.initTestEnvironment(
//  BrowserDynamicTestingModule, 
//  platformBrowserDynamicTesting() 
// ); 


    let pipe: LiteralPipe; 
    let msgService: MessageService; 
//////// SPECS ///////////// 
describe('LiteralPipe',() => { 
    beforeEach(()=>{ 
    [addProviders([MessageService]) ] 
    }); 

 TestBed.configureTestingModule({ 
    declarations:[MessageService], 
    providers: [{provide:MessageService, useClass:MessageService } ], 
    imports: [MessageService, Http] 
    }); 
    it('can get an instance', inject([MessageService], (msgService: MessageService) => { 
    //create instance of pipe using msgService as the instance of service. 
    pipe = new LiteralPipe(msgService); 
  })); 
    it('transforms "Home.title" to "Login"',() => { 
    expect(pipe.transform('Home.title', null)).toEqual('Login'); 
    }); 
}); 

它看起來像我在規範文件中去,當我運行NPM測試和查看錯地方在瀏覽器中打開的unitTests我得到以下例外:

LiteralPipe can get an instance 
TypeError: Cannot read property 'injector' of null 
TypeError: Cannot read property 'injector' of null 
    at TestBed._createCompilerAndModule (http://localhost:3000/node_modules/@angular/core/testing/test_bed.js:246:44) 
    at TestBed._initIfNeeded (http://localhost:3000/node_modules/@angular/core/testing/test_bed.js:213:39) 
    at TestBed.execute (http://localhost:3000/node_modules/@angular/core/testing/test_bed.js:274:14) 
    at Object.eval (http://localhost:3000/node_modules/@angular/core/testing/test_bed.js:404:45) 
    at attemptSync (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1886:24) 
    at QueueRunner.run (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1874:9) 
    at QueueRunner.execute (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1859:10) 
    at Spec.queueRunnerFactory (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:697:35) 
    at Spec.execute (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:359:10) 
    at Object.fn (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:2479:37) 
LiteralPipe transforms "Home.title" to "Login" 
TypeError: Cannot read property 'transform' of undefined 
TypeError: Cannot read property 'transform' of undefined 
    at Object.eval (http://localhost:3000/app/literal.pipe.spec.js:30:20) 
    at attemptSync (http://localhost:3000/node_modules/jasmine-core/lib/jasmine-core/jasmine.js:1886:24) 

我應該更改哪些內容才能完成此項工作。

回答

2

這裏的問題是你正在使用TeseBed不正確。以下示例是您的literal.pipe.spec.ts文件的修改版本。

主要的是你必須在初始化之前重置測試環境。

 

    TestBed.resetTestEnvironment(); 

一旦環境是重置的configureTestingModule必須配置:

 

    TestBed 
    .initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()) 
    .configureTestingModule({providers: [MessageService],imports: [HttpModule]}); 

import {By}    from '@angular/platform-browser'; 
 
import {provide}  from '@angular/core'; 
 
import {ViewMetadata} from '@angular/core'; 
 
import {LiteralPipe} from './pipe/literal.pipe'; 
 
import {MessageService} from '../services/message.service'; 
 
import {Http} from '@angular/http'; 
 
import {inject, TestBed} from '@angular/core/testing'; 
 
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from "@angular/platform-browser-dynamic/testing"; 
 
import {HttpModule} from '@angular/http'; 
 

 
let pipe: LiteralPipe; 
 
let msgService: MessageService; 
 
//////// SPECS ///////////// 
 
describe('LiteralPipe',() => { 
 
    beforeEach(() => { 
 
    // Must reset the test environment before initializing it. 
 
    TestBed.resetTestEnvironment(); 
 

 
    TestBed 
 
     .initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()) 
 
     .configureTestingModule({ 
 
     declarations: [], 
 
     providers: [ 
 
      MessageService 
 
     ], 
 
     imports: [ 
 
      HttpModule 
 
     ] 
 
     }); 
 
    }); 
 
    
 
    it('transforms "Home.title" to "Login"', inject([MessageService], (msgService: MessageService) => { 
 
    let pipe = new LiteralPipe(msgService); 
 
    expect(pipe.transform('Home.title', null)).toEqual('Login'); 
 
    }) 
 
); 
 
});


也可能是您的管道實施方案本身就是一個問題。在嘗試從中獲取值之前,應該檢查args變量是否爲空。

literal.pipe.ts

 


    if(this.messageBundle[value]) 
      return this.messageBundle[value]; 
     else if(args != null && args[0]) 
      return args; 
     else 
      return "String not available. Pls include in bundle.json";