Skip to main content

Part 4: Appendix

·4 mins

This article is part of a series: Introduction to Jest

    Using Jest with VSCode #

    The main Jest plugin for VSCode is here: Jest - Visual Studio Marketplace

    There is a config setting to turn off running tests automatically on save - add the following line to your settings.json file:

    "jest.autoRun": "off",
    

    The plugin is known to not work so well with yarn workspaces. In this case, it may be easier to simply use the CLI commands:

    Jest CLI Options ยท Jest (jestjs.io)

    Hacks #

    Boolean logic for Expect statements #

    We can write a fairly comprehensive test by using multiple expect statements in one test. ie:

    it('Does 2 things', () => {
      expect(thingOne).toBeTruthy();
      expect(thingTwo).toBeTruthy();
    });
    

    This gives us the equivalent of a logical AND statement - if anything fails, the whole test fails.

    Jest, however, doesn’t support logical OR on first inspection, ie:

    it('Does one of 2 things', () => {
      expect(result).toBe(thingOne jest.or thingTwo);
    });
    

    This makes sense somewhat, a unit really shouldn’t have 2 equally valid outputs for 1 input.

    However occasionally we might test something where it is helpful - like testing a mock where the call order doesn’t matter.

    In this case we can wrap the expect in a try/catch , and it will take either option. Example:

    it('Calls the mock service with one of 2 arg sets', () => {
      try{
        expect(mockService).toBeCalledWith({ argA: 'myArgA', argB: 'myArgB' });
      } catch {
        expect(mockService).toBeCalledWith({ argA: 'yourArgA', argB: 'yourArgB' });
      }
    });
    

    In this case, only 1 of the expect statements is required for the test to pass.

    Samples #

    Expressiveness #

    Here is a very expressive sample for a date/time validation function.

    Using such detailed samples allows us to find the exact places and edge cases that a service might fail if adjusted.

    describe('validateDateTimeString', () => {
        describe('Date strings', () => {
            it('Accepts a well formatted string', () => {
                expect(validateDateTimeString('01/01/2021', 'dd/MM/yyyy')).toBeTruthy();
            });
    
            it("Rejects a string that requires leading zeroes, but doesn't supply them", () => {
                expect(validateDateTimeString('1/1/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date where the year position is not where it is expected', () => {
                expect(validateDateTimeString('2021/01/01', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date where the day value is larger than can be in any month', () => {
                expect(validateDateTimeString('90/01/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date where the month value is larger than 12', () => {
                expect(validateDateTimeString('01/90/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date where the year value is longer than the required four digits', () => {
                expect(validateDateTimeString('01/01/12021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date where the day value (40) is larger than can be for a given month', () => {
                expect(validateDateTimeString('40/08/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date where the day value is in the months column (ie - American formatting)', () => {
                expect(validateDateTimeString('04/30/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Accepts a date where the day value (30) is within the given month (April)', () => {
                expect(validateDateTimeString('30/04/2021', 'dd/MM/yyyy')).toBeTruthy();
            });
    
            it('Rejects a date where the day value (31) is larger than can be for a given month (April)', () => {
                expect(validateDateTimeString('31/04/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Accepts a date where the day value (31) is within the given month (January)', () => {
                expect(validateDateTimeString('31/01/2021', 'dd/MM/yyyy')).toBeTruthy();
            });
    
            it('Rejects a date where the day value (32) is larger than can be for a given month (January)', () => {
                expect(validateDateTimeString('32/01/2021', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Accepts a date where the day value (28) exists for the given February (2022)', () => {
                expect(validateDateTimeString('28/02/2022', 'dd/MM/yyyy')).toBeTruthy();
            });
    
            it('Rejects a date where the day value (29) does not exist for the given February (2022)', () => {
                expect(validateDateTimeString('29/02/2022', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Accepts a date where the day value (29) exists for the given February (2024)', () => {
                expect(validateDateTimeString('29/02/2024', 'dd/MM/yyyy')).toBeTruthy();
            });
    
            it('Rejects a date where the day value (30) does not exist for the given February (2024)', () => {
                expect(validateDateTimeString('30/02/2024', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Accepts a date where the day value (28) exists for the given February (2100)', () => {
                expect(validateDateTimeString('28/02/2100', 'dd/MM/yyyy')).toBeTruthy();
            });
    
            it('Rejects a date where the day value (29) does not exist for the given February (2100)', () => {
                expect(validateDateTimeString('29/02/2100', 'dd/MM/yyyy')).toBeFalsy();
            });
    
            it('Rejects a date that is given in English instead of the required date string', () => {
                expect(validateDateTimeString('1st of January 2021', 'dd/MM/yyyy')).toBeFalsy();
            });
        });
    
        describe('Time strings', () => {
            it('Accepts a time string that is formatted correctly for the given format', () => {
                expect(validateDateTimeString('01:01:01', 'HH:mm:ss')).toBeTruthy();
            });
    
            it('Rejects a time with an hour value that is too high', () => {
                expect(validateDateTimeString('60:01:01', 'HH:mm:ss')).toBeFalsy();
            });
    
            it('Rejects a time with a minute value that is too high', () => {
                expect(validateDateTimeString('01:90:01', 'HH:mm:ss')).toBeFalsy();
            });
    
            it('Rejects a time with a second value that is too high', () => {
                expect(validateDateTimeString('01:01:90', 'HH:mm:ss')).toBeFalsy();
            });
    
            it('Rejects a time with a value written in english, instead of the required date format', () => {
                expect(validateDateTimeString('midnight', 'HH:mm:ss')).toBeFalsy();
            });
        });
    });
    

    This article is part of a series: Introduction to Jest

      Luka Lydia Hedt
      Author
      Luka Lydia Hedt
      I’m a developer in Australia with 5+ years engineering and tech team leadership experience. I focus broadly on API and Database development, but I have some experience with making Games, Web Development and a whole lot of Infrastructure Coding.

      I just want a world full of better, more reliable software.

      comments powered by Disqus