I have the following jasmine test spec which triggers the mouse events in my directive. As you can see there is a lot of code duplication here, I am repeating the events here.
describe('Test for my module', () => {
let fixture: ComponentFixture<TestComponent>;
let de: DebugElement[];
let service: MyService = new MyService();
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [Move, TestComponent],
providers: [MyService]
});
fixture = TestBed.createComponent(TestComponent);
service = fixture.debugElement.injector.get(MyService);
fixture.detectChanges();
de = fixture.debugElement.queryAll(By.directive(Move));
});
// My test spec. This is where I need advice for removing the code duplication.
it('test the move event', inject([MyService], (service: MyService) => {
let object = spyOn(service.x, 'emit');
spyObj.and.callThrough();
de[0].triggerEventHandler('mousedown', { pageX: 10, pageY: 10 });
de[0].triggerEventHandler('mousemove', { pageX: 40, pageY: 20 });
expect(service.x.emit).toHaveBeenCalledWith({ x: 30, y: 10 });
object.calls.reset();
de[0].triggerEventHandler('mousemove', { pageX: 45, pageY: 25 });
expect(service.x.emit).toHaveBeenCalledWith({ x: 35, y: 15 });
object.calls.reset();
de[0].triggerEventHandler('mousemove', { pageX: 50, pageY: 30 });
expect(service.x.emit).toHaveBeenCalledWith({ x: 40, y: 20 });
}));
Could anyone help me by suggesting any way to avoid this duplication?
-
\$\begingroup\$ I was wondering if I can use an inline function here to avoid duplication? \$\endgroup\$ShellZero– ShellZero2017年06月08日 16:39:12 +00:00Commented Jun 8, 2017 at 16:39
1 Answer 1
I did come up with one alternative which is as follows:
function triggerEvents(debugElement: DebugElement, eventName: string, object: any){
debugElement.triggerEventHandler(eventName, object);
}
function expectAndReset(spy: Function, object: any, spyObj: jasmine.Spy) {
expect(spy).toHaveBeenCalledWith(object);
spyObj.calls.reset();
}
it('test the move event', inject([MyService], (service: MyService) => {
let spyObj = spyOn(service.x, 'emit');
spyObj.and.callThrough();
triggerEvents(de[0],'mousedown', { pageX: 10, pageY: 10 });
triggerEvents(de[0],'mousemove', { pageX: 40, pageY: 20 });
expectAndReset(service.x.emit,{ x: 30, y: 10 },spyObj);
triggerEvents(de[0],'mousemove', { pageX: 45, pageY: 25 });
expectAndReset(service.x.emit,{ x: 35, y: 15 },spyObj);
triggerEvents(de[0],'mousemove', { pageX: 50, pageY: 30 });
expectAndReset(service.x.emit,{ x: 40, y: 20 },spyObj);
}));
I am not really satisfied with my own solution though, because the function implementation of triggerEvents is almost identical as the triggerEventHandler in the Angular Documentation. I am not doing anything special there. But I am hoping that the code reviewers on the community would comment or share their views and give me a better solution :)
Second Attempt:
function triggerEvents(debugElement: DebugElement, eventName: string, object: any) {
debugElement.triggerEventHandler(eventName, object);
}
function expectAndReset(spy: Function, object: any, spyObj: jasmine.Spy) {
expect(spy).toHaveBeenCalledWith(object);
spyObj.calls.reset();
}
it('test the move event', inject([MyService], (service: MyService) => {
let spyObj = spyOn(service.x, 'emit');
spyObj.and.callThrough();
triggerEvents(de[0], 'mousedown', { pageX: 10, pageY: 10 });
for (let i = 0; i <= 10; i += 5) {
triggerEvents(de[0], 'mousemove', { pageX: 40 + i, pageY: 20 + i });
expectAndReset(service.x.emit, { x: 30 + i, y: 10 + i }, spyObj);
}
}));
Somewhat satisfied with my second iteration.
Thank you.
-
1\$\begingroup\$ You are fantastic!!! \$\endgroup\$Padmapriya Vishnuvardhan– Padmapriya Vishnuvardhan2020年01月31日 11:05:52 +00:00Commented Jan 31, 2020 at 11:05
Explore related questions
See similar questions with these tags.