Tom Rudge
Tom Rudge

Reputation: 3272

Mock an if/else statement with jasmine - unit testing with Angular/Typescript

I have added a minor amendment within an existing function. Our quality checks have identified this as new code therefore I need to cover the new 4 lines with a unit test - within mind there was never a unit test there to begin with and the function I added to is pretty large!

I've tried a number of ways to try and mock services, variables, spying etc... but always get errors. I'm new to jasmine so struggling. All I need to do is get any sort of check to cover the lines truthy/falsy.

component.ts file

hasDescription() {
        return this.isBrilliant() || this.isCool();
    }

isBrilliant() {
        return this.service.Type.description == 'Brilliant';
    }

isCool() {
        return this.service.Type.description == 'Cool';
    }



onExportToExcel(): void {
        var r = [];
        // added the below if/else - any check on this will be suffice.
        if (this.hasDescription()) {
            if (!this.isBrilliant()) {
                r.push('This is Cool');
            } else {
                r.push('This is Brilliant');
            }
            if (!this.isBrilliant()) {
            r.push('More Cool content');
            }
        }
}

I tried to set isBrilliant() with a mock value of true, and expect that the value to be truthy expect(component.isBrilliant()).toBeTruthy();

I tried to set this in the spec file by:

const isBrilliant = true;
component.isBrilliant = isBrilliant;

however the error I got here was that Type 'true' is not assignable to type '() => boolean'.

If any experienced jasmine dev can show me a quick way to get some coverage for this simple statement that would be appreciated. Thanks


UPDATE:

I can get isBrilliant() to be true or false. I now need to check the array r to see if the correct string has been .push into it? any ideas?

Upvotes: 2

Views: 15677

Answers (1)

Shashank Vivek
Shashank Vivek

Reputation: 17494

There are few changes that I would suggest as a part of best practices.

  1. Dont mock component method, because you need to test them. In your case, you should set value of this.service.Type.description and accordingly it should return true or false. That would be a correct approach.

If this.service is a service which has been injected on the construtor, you can mock the service. Refer this article to understand mocking here

  1. Since you are testing several conditions using if else , you need to write few it blocks to have a good test coverage.

  2. To test var r , you should declare it as public variable on component level rather than inside the function. Also prefer let over var.

Here is a sample code which you can write to set the value in isBrilliant()

it('should push Brilliant when the Description is so,()=>{
   component.service.Type.description = 'Brilliant';
   component.onExportToExcel();
   expect(component.r.length).toBe(1);
   expect(component.r[0]).toBe('This is Brilliant');
})

it('should push other cool content when the Description is not Brilliant,()=>{
   component.service.Type.description = 'something else';
   component.onExportToExcel();
   expect(component.r.length).toBe(2);
   // check other values in expect block accordingly
})

// you should also check that "component.r" has zero length when hasDescription() returns false

I hope above code snippet will give you a good start

Upvotes: 1

Related Questions