2017-10-10 106 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對象。所以你可以很容易地監視他們。

我已經創建了一個包含特定用例的輕量級組件。

以下是部分:在這裏我不知道該Attachment類型是什麼

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

 
}

注意。所以我已經將這個類型的註釋從參數中移除到了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塊中,我將它分配給一個對象,該對象包含一個名爲getFile的鍵,其值爲最終返回字符串foo的函數。

此外,由於您的測試默認在Chrome中運行,因此window.navigator對象上的msSaveOrOpenBlob函數將不會獲得。所以openAttachment describe塊中的第一個測試只會覆蓋else塊。

雖然在第二個測試中,我們在window.navigator對象上添加了msSaveOrOpenBlob作爲函數。所以現在它可以覆蓋if分支。所以,你可以在msSaveOrOpenBlob函數創建一個間諜和expect這個間諜toHaveBeenCalledWith無論是從attachment.getFile()方法(字符串foo在這種情況下)返回

希望這有助於。