Bingo for meetings–obsolete–part 6
Bingo
Bingo is a small project, written in TypeScript , and developed with Alexandru Badita in launch break (one hour - more or less). You can find sources at https://github.com/alexandru360/PresentationBingoCards/ . Those are my blog posts for Bingo : ( scroll below for the post)The requirement says:
Meeting Obsolete:
The meeting is available for 35 minutes. After that, meeting is not available anymore.
How we can implement this ? Several solutions:
- Make the meeting know about this ( and avoiding https://martinfowler.com/bliki/AnemicDomainModel.html )
- Make a decorator class for this https://en.wikipedia.org/wiki/Decorator_pattern
- Make a mixin in TypeScript https://www.typescriptlang.org/docs/handbook/mixins.html
I decide to KISS (https://en.wikipedia.org/wiki/KISS_principle ) and take the first point. We implement an Obsolete function. Remains who is responsible of the site to call it.
Now comes other question: When the meeting startsĀ ?I consider ( for the sake of easy path) that a meeting starts when it is created . So the code is like this
export default class Meeting{ constructor(){ this.Participants = []; this.Cards = []; this.startedMeeting = Date.now(); } public static MaxTime=35 * 60 * 1000; // other code here public IsObsolete(): boolean{ return (this.PassedTimeFromStart() > Meeting.MaxTime); //35 minutes } public PassedTimeFromStart():number{ let dtNow = Date.now(); console.log(dtNow); return (dtNow - this.startedMeeting ); }
Now the problem arises when testing code. It is very easy to say that a meeting is not obsolete when just created. However , I do not want to wait for 35minutes + 1 second in order for a meeting to become obsolete and the test to be successful( see
//TODO: wait 35 minutes + 1 second
below).
import MeetingsFactory from '../MeetingsFactory'; import Meeting from '../meeting'; describe('Meeting Obsolete', () => { it('meeting should not be obsolete after creation', () => { const mf=new MeetingsFactory(); const m1=mf.CreateMeeting("andrei","first meeting"); expect(m1.IsObsolete()).toBe(false); }) it('meeting should be obsolete after 35 minutes', () => { const mf=new MeetingsFactory(); const m1=mf.CreateMeeting("andrei","first meeting"); //TODO: wait 35 minutes + 1 second expect(m1.IsObsolete()).toBe(true); }) })
One possible resolution is https://ayende.com/blog/3408/dealing-with-time-in-tests . However, the problem is so common that here must be include in the test framework ( in this case, jest). And , indeed, it is a way: spyon. So the code is modified accordingly :
it('meeting should be obsolete after 35 minutes', () => { const mf=new MeetingsFactory(); const m1=mf.CreateMeeting("andrei","first meeting"); const now = Date.now(); const spy = jest.spyOn(Date,'now'); spy.mockImplementation(()=>{ console.log('calling DateTime Now'); return now + 36 * 60* 1000; } ); expect(m1.IsObsolete()).toBe(true); //spy.mockClear(); spy.mockRestore(); expect(m1.IsObsolete()).toBe(false); })
The testing code now assumes that he knows inner working of the code – and the test will fail if we modify the call of Date.now().
So I think that https://ayende.com/blog/3408/dealing-with-time-in-tests is far superior.
Leave a Reply