terahertz
terahertz

Reputation: 3491

Angular Karma/Jasmine unit test case: Scope of test

I have read several guides on unit testing and I understand that in unit testing, I am only supposed to test the logic in that component. Any children component should be tested separately. However, I am still confused about what to test.

E.g. scenario I have an overview component which has 2 children components, <app-refresh-button> and <canvas baseChart ...>, which is using a wrapper lib, ng2-charts (chartjs).

<h1>Overview</h1>

<app-refresh-button 
  [isLoading]="isLoading"
  (onIntervalChange)="onSelectNewInterval($event)" 
  (onRefresh)="onRefreshManualClick($event)">
</app-refresh-button>

<canvas baseChart 
    [datasets]="lineChartData"
    ... ...
    (chartclick)="onChartClicked($event)"
</canvas>

Upon clicking on the refresh button, data points will be inserted into the lineChartData array and be plotted on the graph.

Now, here's where I am confused:

Upvotes: 0

Views: 1095

Answers (2)

Erbsenkoenig
Erbsenkoenig

Reputation: 1659

This question is hard to answer, because it's very opinion based.

But personally, I would test all the property bindings and event bindings on those child components without testing, that the actual child component does the right thing with those in- and outputs.

A useful setup for this is setting the NO_ERRORS_SCHEMA inside your TestBed setup.

Having this setup, for the event bindings you can use the triggerEventHandler.

const debugElem = fixture.debugElement.get(By.css('app-refresh-button'));
debugElem.triggerEventHandler('onIntervalChange', THE_EVENT_DATA_YOU_WANT_TO_USE_INSIDE_THE_TEST)

tick();

expect()...

For the property bindings you can access those properties from the debugElement as well:

const debugElem = fixture.debugElement.get(By.css('app-refresh-button'));
expect(debugElem.properties['isLoading']).toEqual(...)

Using those constructs you can test that one output from the refresh-button changes the input in your canvas and so on but you don't test what the components do with those in- and outputs.

Hope this helps.

Upvotes: 1

Buczkowski
Buczkowski

Reputation: 2416

Since is a child component, I do not test it in unit test, is that correct?

Yes, you shouldn't test it in unit tests.

If so, the logic in refresh button and the plotting of the graph is linked together, if I do not test them together, how do I know they are working together???

I believe there are two options:

  1. Shallow/Integration tests - in those tests you provide real components and dependencies. Then you can check interaction between them since there is real implementation behind. What you should cut off are heavy services/modules like HttpClientModule, RouterModule or provide their testing equivalents.
  2. Second option - do not provide real children components instead create really simple mocks of those components that allow you test your cases (events, if data is set etc.). With that done you can trigger event by triggerEventHandler method from DebugElement. There is also option to not provide children components at all (care with that) - https://angular.io/guide/testing#no_errors_schema then trigger events with dispatchEvent method from HTMLElement.

What about functions such as "pushingNewDataPoints()", which pushes new data into the lineChartData array, that are also in this overview component, do I test them?

It looks like lineChartData is public so you can trigger event on app-refresh-button that changes lineChartData and then check if contains correct values.

Upvotes: 1

Related Questions