2017-10-10 36 views
1

を使用して、私はそれをテストするために、窓やモックウィンドウへのアクセスを取得する方法がわからないコード角度4ユニットテストコードウィンドウ

public openAttachment(attachment: Attachment) { 
    if (window.navigator && window.navigator.msSaveOrOpenBlob) { 
     window.navigator.msSaveOrOpenBlob(attachment.getFile()); 
    } 
    else { 
     let objectUrl = URL.createObjectURL(attachment.getFile()); 
     window.open(objectUrl); 
    } 
} 

をテストしたいと思います。私は角試験を初めてやっているので、あなたが私を詳細に説明してくれたら嬉しいです!

答えて

1

あなたはテストでwindowオブジェクトにアクセスすることができます。だからあなたは簡単にスパイすることができます。

私は、特定の用途に合わせて軽量コンポーネントを作成しました。

import { Component } from '@angular/core'; 
 

 
@Component({ 
 
    selector: 'app-attachment', 
 
    templateUrl: './attachment.component.html', 
 
    styleUrls: ['./attachment.component.css'] 
 
}) 
 
export class AttachmentComponent { 
 

 
    public openAttachment(attachment) { 
 
    if (window.navigator && window.navigator.msSaveOrOpenBlob) { 
 
     window.navigator.msSaveOrOpenBlob(attachment.getFile()); 
 
    } 
 
    else { 
 
     let objectUrl = URL.createObjectURL(attachment.getFile()); 
 
     window.open(objectUrl); 
 
    } 
 
    } 
 

 
}

注ここで私はAttachmentタイプが何であるかわからない:

後は、コンポーネントです。だから私はそのタイプの注釈を、openAttachment関数へのパラメータから削除しました。

そして今、これは私のテストはどのように見えるべきかです:

再び

import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 
 

 
import { AttachmentComponent } from './attachment.component'; 
 

 
describe('AttachmentComponent',() => { 
 
    let component: AttachmentComponent; 
 
    let fixture: ComponentFixture<AttachmentComponent>; 
 

 
    beforeEach(async(() => { 
 
    TestBed.configureTestingModule({ 
 
     declarations: [ AttachmentComponent ] 
 
    }) 
 
    .compileComponents(); 
 
    })); 
 

 
    beforeEach(() => { 
 
    fixture = TestBed.createComponent(AttachmentComponent); 
 
    component = fixture.componentInstance; 
 
    fixture.detectChanges(); 
 
    }); 
 

 
    it('should be created',() => { 
 
    expect(component).toBeTruthy(); 
 
    }); 
 

 
    describe('openAttachment',() => { 
 
    let attachment; 
 
    beforeEach(() => { 
 
     attachment = { getFile: function() { return 'foo'; } }; 
 
    }); 
 

 
    it('should call `window.open` if `msSaveOrOpenBlob` is not a method present on the `window.navigator`',() => { 
 

 
     // Since this will probably run on Chrome, Chrome Headless or PhantomJS, if won't have a `msSaveOrOpenBlob` method on it. 
 
     // So this is the test for the else condition. 
 
     let windowOpenSpy = spyOn(window, 'open'); 
 
     let returnValue = { foo: 'bar' }; 
 
     let urlCreateObjectSpy = spyOn(URL, 'createObjectURL').and.returnValue(returnValue); 
 

 
     component.openAttachment(attachment); 
 

 
     expect(urlCreateObjectSpy).toHaveBeenCalledWith('foo'); 
 
     expect(windowOpenSpy).toHaveBeenCalledWith(returnValue); 
 

 
    }); 
 

 
    it('should call the `window.navigator.msSaveOrOpenBlob` if `msSaveOrOpenBlob` is present on the navigator object',() => { 
 

 
     // To cover the if condition, we'll have to attach a `msSaveOrOpenBlob` method on the window.navigator object. 
 
     // We can then spy on it and check whether that spy was called or not. 
 
     // Our implementation will have to return a boolean because that's what is the return type of `msSaveOrOpenBlob`. 
 
     window.navigator.msSaveOrOpenBlob = function() { return true; }; 
 
     let msSaveOrOpenBlobSpy = spyOn(window.navigator, 'msSaveOrOpenBlob'); 
 

 
     component.openAttachment(attachment); 
 

 
     expect(msSaveOrOpenBlobSpy).toHaveBeenCalledWith('foo'); 
 

 
    }); 
 

 
    }); 
 

 
});

私は、添付ファイルの種類がために何が起こっているかわからないという事実を重視したいのですがさあ。だから私のopenAttachmentブロックのbeforeEachブロックには、ブロックfooを最終的に返す関数として値を持つgetFileという名前のキーを含むオブジェクトに割り当てています。

また、デフォルトでChromeでテストが実行されているため、機能はwindow.navigatorオブジェクトにはありません。したがって、ブロックを記述するopenAttachmentの最初のテストでは、elseブロックのみが対象となります。

しかし、2番目のテストでは、msSaveOrOpenBlobを関数としてwindow.navigatorオブジェクトに追加しました。だから今度はifブランチをカバーすることができます。だから、あなたは(この場合には、文字列fooattachment.getFile()メソッドから返されるものは何でも、このスパイtoHaveBeenCalledWithこのことができます

希望をmsSaveOrOpenBlob機能にスパイを作成し、expectすることができます。