我正在为angular应用编写单元测试,正在测试服务功能是否返回值。
component.spec.ts
import {TopToolBarService} from '../../top-toolbar/top-toolbar.service';
beforeEach(async(() => {
TestBed.configureTestingModule ({
declarations: [ UsersListComponent],
providers: [TopToolBarService],//tried mocking service here,still test failed
schemas:[CUSTOM_ELEMENTS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UserListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should return data from service function', async(() => {
let mockTopToolBarService: jasmine.SpyObj<TopToolBarService>;
mockTopToolBarService = jasmine.createSpyObj('TopToolBarService', ['getCustomer']);
mockTopToolBarService.getCustomer.and.returnValue("king");
fixture.detectChanges();
expect(component.bDefine).toBe(true); //fails
}))
component.ts
bDefine = false;
ngOnInit() {
let customer = this.topToolBarService.getCustomer();
if (customer == null) {
bDefine = false;
} else {
bDefine = true;
}
}
我相信我在测试中嘲笑了服务函数,因此我希望它必须到达变量设置为“ true”的其他部分。
TopToolBarService.ts
import { EventEmitter, Injectable, Output } from "@angular/core";
@Injectable()
export class TopToolBarService {
customer = null;
getCustomer() {
return this.customer;
}
}
答案 0 :(得分:1)
尝试更新beforeEach(async(()=> ...)内的提供程序,并将您的mockedService变量移至其顶部:
(keyup)="onKey($event)"
希望有帮助!
答案 1 :(得分:1)
更改您的提供商价值
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ UsersListComponent],
providers: [{
provide: TopToolBarService,
useValue: jasmine.createSpyObj('TopToolBarService', ['getCustomer'])
}],
schemas:[CUSTOM_ELEMENTS_SCHEMA]
});
mockTopToolBarService = TestBed.get(TopToolBarService);
mockTopToolBarService.getCustomer.and.returnValue(of([])); // mock output of function
})
答案 2 :(得分:0)
在运行代码之前,您必须配置测试模块。除非您将其作为导入对象传递给TestBed.configureTestingModule
,否则它不会知道您的间谍对象。
https://angular.io/guide/testing#component-with-a-dependency
答案 3 :(得分:0)
您可以考虑使用 ng-mocks 来避免配置 TestBed
的所有样板。
beforeEach(() => MockBuilder(UsersListComponent)
.mock(TopToolBarService, {
// adding custom behavior to the service
getCustomer: jasmine.createSpy().and.returnValue('king'),
})
);
it('should return data from service function', () => {
const fixture = MockRender(UsersListComponent);
// now right after the render the property should be true
expect(fixtur.point.componentInstance.bDefine).toBe(true);
}));
答案 4 :(得分:0)
@Pedro Bezanilla 的回答已经足够好了。这是另一种代码更少的方法,因为服务是单例,我认为这是大多数情况。
不同之处在于没有为 configureTestingModule
提供提供程序配置。间谍是由 spyOn
针对从 TestBed 获取的服务对象设置的。
调用 TestBed.inject
而不是 TestBed.get
是因为它自 v9.0.0 以来已被弃用。
对于单例服务,这里是a doc in Angular website,为了完成,请记住this GitHub issue。
describe('Component TEST', () => {
...
let mockToolBarService: TopToolBarService;
...
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ UsersListComponent ],
schemas:[ CUSTOM_ELEMENTS_SCHEMA ]
});
mockTopToolBarService = TestBed.inject(TopToolBarService);
spyOn(mockTopToolBarService, 'getCustomer').and.returnValue(of([]));
}));
...