I Stand With Israel
I Stand With Israel

Reputation: 2387

How to get results from method into spec.js testing file?

I have been given a challenge and must write code that passes tests that checks to see if my method produces a specific URL path string. My method correctly creates the URL path string but, since I have no experience with unit testing, I am not sure how the test attempt to evaluate my code. I was given the tests and must ensure that they pass when npm test is run.

I am mainly having difficulty seeing the results of my method in the spec.js file when I run npm test. The test I was given (below) creates an empty url string and then tests it, which seems strange. When I call the method itself by inserting this.app.generateURLMethod and saving its value to a variable, it says that that method has returned an undefined value.

Here are two testing examples:

app.component.spec.ts

describe('API', () => {
       it('should add a greater than or equal to filter to the url', () => {
        const url = '';
        expect(url).toBe('/items?price_gte=100');
    });
    it('should add a less than filter to the url', () => {
        const url = '';
        expect(url).toBe('/items?price_lt=1000');
    });
});

Here is my method that creates the URL string:

app.component.ts

import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

 userType = 'customer'; // Default user type is customer.
  lessThanValue;
  greaterThanValue;

  filterAdded;
  urlPathString;

constructor() {}

generateURLMethod(userType, greaterThanValue, lessThanValue, limitValue, offsetValue) {
    this.filterAdded = false;
    this.urlPathString = (`/${this.userType}`);

    if (greaterThanValue) {
        this.urlPathString += (`?price_gte=${greaterThanValue}`);
        this.filterAdded = true;
    }

    if (lessThanValue) {
      if (this.filterAdded === false) {
        this.urlPathString += (`?price_lt=${lessThanValue}`);
        this.filterAdded = true;
      } else {
        this.urlPathString += (`&price_lt=${lessThanValue}`);
      }
    }
window.location.href = this.urlPathString;

}

Upvotes: 1

Views: 1266

Answers (1)

I Stand With Israel
I Stand With Israel

Reputation: 2387

I resolved my question and want to post the solution here, in case it helps someone in the future.

Although I had never dealt with Unit testing before I read the Angular 2 testing docs (here) on how to run unit tests on components. I learned that although I had been given the tests I was supposed to pass I was missing the initialization settings as well as the actual code that runs the functions. Here is the completed test file which runs successfully and passes.

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { ComponentFixtureAutoDetect } from '@angular/core/testing';
import { hostElement } from '@angular/core/src/render3/instructions';
import { HtmlParser } from '@angular/compiler';
describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [ FormsModule ],
      declarations: [
        AppComponent
      ],
      providers: [
        { provide: ComponentFixtureAutoDetect, useValue: true }
      ],
    }).compileComponents();
  }));

  describe('API', () => {
    it('should build the url for the employees endpoint', () => {
        const fixture = TestBed.createComponent(AppComponent);
        const url = fixture.componentInstance.generateURLMethod('employees');
        expect(url).toBe('/employees');
    });

});

To explain a bit, I inserted the standard testing initialization setup that Angular automatically creates. I then added FormsModule (import on top and also in the TestBed configuration). I also added AutoDetect as a provider to auto detect changes, which may not be necessary, especially since I didn't call it explicitly. I then called the function and stored the return value into a variable.

Then, in the actual tests I learned that you need to instantiate a component since testing doesn't actually run your entire project but rather sections of it.

How It Worked

This instantiated the component. const fixture = TestBed.createComponent(AppComponent);

This assigned the return value of my function from my component to a variable. const url = fixture.componentInstance.generateURLMethod('items?price_gte=100');

Finally, that variable containing my URL string was evaluated against the predefined test condition expect(url).toBe('/items?price_gte=100');

Upvotes: 1

Related Questions