我正在尝试为角度服务编写测试,该服务具有Subject属性和在该主题上调用.next()
的方法。
该服务如下:
@Injectable()
export class SubjectService {
serviceSubjectProperty$: Subject<any> = new Subject();
callNextOnSubject(data: any) {
this.serviceSubjectProperty$.next(data);
}
}
该服务的测试文件:
import { TestBed, inject } from '@angular/core/testing';
import { SubjectService } from './subject.service';
describe('SubjectService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
SubjectService
]
});
});
it('callNextOnSubject() should emit data to serviceSubjectProperty$ Subject',
inject([SubjectService], (subjectService) => {
subjectService.callNextOnSubject('test');
subjectServiceProperty$.subscribe((message) => {
expect(message).toBe('test');
})
}));
});
如果我将subjectService.callNextOnSubject
的参数从'test'
更改为其他任何内容,则测试始终会传递事件。
我还尝试使用async
和fakeAsync
包装所有内容,但效果相同。
测试callNextOnSubject
是否向serviceSubjectProperty$
主题发送数据的正确方法是什么?
答案 0 :(得分:8)
我在搜索解决方案时发现了这篇文章:
http://www.syntaxsuccess.com/viewarticle/unit-testing-eventemitter-in-angular-2.0
它对我来说效果很好(它很短,不要害怕打开它)。
我在这里粘贴它,所以它可能会帮助那些来到这个网站寻找答案的人。
关于提出的问题 - 我认为你需要改变:
string x = Convert.ToString(int.Parse(_dataRx), 2).PadLeft(8, '0');
到
subjectService.callNextOnSubject('test');
subjectServiceProperty$.subscribe((message) => {
expect(message).toBe('test');
})
,所以先订阅,然后发出一个事件。
如果您在订阅之前发出 subjectServiceProperty$.subscribe((message) => {
expect(message).toBe('test');
})
subjectService.callNextOnSubject('test');
,那么什么都不会“捕获”该事件。
答案 1 :(得分:1)
在调用主题后,您应该测试组件中更改的数据。应该只测试公共变量,而不是私有或受保护; 例如:
服务:
@Injectable()
export class SomeService {
onSomeSubject: Subject<any> = new Subject();
someSubject(string: string) {
this.onSomeSubject.next(string);
}
}
成分:
export class SomeComponent {
@Input() string: string;
constructor(private service: SomeService) {
service.onSomeSubject.subscribe((string: string) => {
this.string = string;
}); //don't forget to add unsubscribe.
}
}
试验:
...
describe('SomeService', () => {
let someService: SomeService; // import SomeService on top
let someComponent: SomeComponent; // import SomeService on top
beforeEach(() => {
TestBed.configureTestingModule({
providers: [SomeService, SomeComponent]
});
injector = getTestBed();
someService = injector.get(SomeService);
someComponent = injector.get(SomeComponent);
});
describe('someSubject', () => {
const string = 'someString';
it('should change string in component', () => {
someService.someSubject(string);
expect(someComponent.string).tobe(string);
});
});
});
答案 2 :(得分:0)
使用茉莉花&#39;完成&#39;回调将到目前为止,检查下面的文档: https://jasmine.github.io/api/edge/global(参见implementationCallback(doneopt))
使用测试用例的示例下面:
it('callNextOnSubject() should emit data to serviceSubjectProperty$ Subject', (done) => {
inject([SubjectService], (subjectService) => {
subjectService.callNextOnSubject('test');
subjectServiceProperty$.subscribe((message) => {
expect(message).toBe('test');
done();
})
}) // function returned by 'inject' has to be invoked
});