2
\$\begingroup\$

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?

asked Jun 7, 2017 at 21:42
\$\endgroup\$
1
  • \$\begingroup\$ I was wondering if I can use an inline function here to avoid duplication? \$\endgroup\$ Commented Jun 8, 2017 at 16:39

1 Answer 1

1
\$\begingroup\$

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.

answered Jun 7, 2017 at 22:37
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You are fantastic!!! \$\endgroup\$ Commented Jan 31, 2020 at 11:05

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.