2017-10-10 118 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在这种情况下)返回

希望这有助于。