How to implement unit tests in NativeScript using TestBed and Jasmine?
Asked Answered
F

3

9

I'm setting up a NativeScript-Angular project, and would like to implement unit tests using Jasmine-Karma in order to test my components using css selectors. How can I setup a simple unit test (beyond the sample test provided on the official repository) for a simple component?

This is for a new project using NativeScript CLI 6.0 with Android API level 28.

I have tried using the regular Angular TestBed which is claimed to be supported on this blog post: https://www.nativescript.org/blog/announcing-the-nativescript-4.1-release

I have also tried following their working tests on the official nativescript-angular repository: https://github.com/NativeScript/nativescript-angular/tree/master/tests

Either way I seem to be doing something wrong when I try to do my own implementation because I get the following errors:
Uncaught Error: Zone already loaded
TypeError: Cannot read property 'injector' of null
TypeError: Cannot read property 'getComponentFromError' of null
TypeError: Cannot read property 'currentPage' of undefined

Has anyone managed to get TestBed unit tests working in NativeScript with Jasmine-Karma?

test-main.ts

import "nativescript-angular/zone-js/testing.jasmine";
import { nsTestBedInit } from "nativescript-angular/testing";
nsTestBedInit();

example.ts

import { ItemsComponent } from '~/app/item/items.component';
import { By } from '@angular/platform-browser';
import { nsTestBedBeforeEach, nsTestBedAfterEach, nsTestBedRender } from 'nativescript-angular/testing';

describe('item-detail-component', () => {
  beforeEach(nsTestBedBeforeEach(
    [ItemsComponent]
  ));
  afterEach(nsTestBedAfterEach());

  it(`should contain items`, () => {
    return nsTestBedRender(ItemsComponent).then((fixture) => {
      fixture.detectChanges();
      const list = fixture.debugElement.query(By.css('.list-group'));

      expect(list).toBeDefined();
    });
  })
});

I am expecting to be able to run the test without getting any errors.

I have included two repos for each test implementation.
Steps to reproduce:
1. Download repo
2. yarn install
3. tns test android

https://github.com/gsavchenko/nativescript-ns-testbed

update

for anyone else wondering how to further test their front-end using end to end tests it seems like appium is the go to https://docs.nativescript.org/plugins/ui-tests

Fordo answered 24/7, 2019 at 15:54 Comment(4)
I think your question is so huge for others to see and try to answer , Please try to make it a bit short and specific about your issue , If you have multiple question try to make one for eachRitual
Yeah I agree I am working on making minimal reproduction steps and repos at the moment.Fordo
I've edited my question to be more bare-bones and my question to be clearer. If any readers would like me to make further simplifications please let me know.Fordo
This is the exact issue I'm having as well. IMO, after adding testing to project with tns test init, performing an action like ng generate service Foo should result in foo.service.spec.ts being included in the tests. However, even after manual intervention as you have here, I can't for the life of me get it to work.Kebab
A
3

To use TestBed you have to alter your karma.conf.js to:

    // list of files / patterns to load in the browser
    files: [
      'src/tests/setup.ts',
      'src/tests/**/*.spec.ts'
    ],

The file src/tests/setup.ts should look like this for jasmine:

import "nativescript-angular/zone-js/testing.jasmine";
import {nsTestBedInit} from "nativescript-angular/testing";
nsTestBedInit();

or if using mocha:

import "nativescript-angular/zone-js/testing.mocha";
import {nsTestBedInit} from "nativescript-angular/testing";
nsTestBedInit();

You'll find a sample here: https://github.com/hypery2k/tns_testbed_sample

Argile answered 1/11, 2019 at 3:13 Comment(1)
This is the solution that most relevantly answers my question and I will come back and mark it as accepted if no other answers mention css selectors or I get them working into a relevant branch on my personal project. Thanks and all the best!Fordo
P
0

I was facing the same issue like you. I finally found a way to make Unit Test in Nativescript-Angular works.

To fix my issue I add beforeAll(() => nsTestBedInit()); and afterAll(() => { }); Also change from TestBed to nsTestBed... I just follow the idea on https://github.com/NativeScript/nativescript-angular/blob/master/tests/app/tests/detached-loader-tests.ts

Also add into tsconfig.tns.json file this line: "include": ["src/tests/*.spec.ts"],

My issue now is split all test into multiple file. Like appComponent in a test file and homeCompenent in a second test file. When the app grow the unit test also grow, we need organize our code.

Here my code (file name: src/tests/test.spec.ts):

    import "reflect-metadata";
    import { AppComponent } from "../app/app.component";
    import { nsTestBedBeforeEach, nsTestBedAfterEach, nsTestBedRender, nsTestBedInit }     from "nativescript-angular/testing";
    import { HomeComponent } from "@src/app/home/home.component";
    describe("AppComponent", () => {
        beforeAll(() => nsTestBedInit());
        afterAll(() => { });
        beforeEach(nsTestBedBeforeEach([AppComponent, HomeComponent]));
        afterEach(nsTestBedAfterEach());
        it("should be: app works!", () => {
            return nsTestBedRender(AppComponent).then((fixture) => {
                fixture.detectChanges();
                const app = fixture.componentInstance;
                expect(app.title).toBe("app works!");
            });
        });
        describe("HomeComponent", () => { 
            it("should contain: Home works!", () => {
              return nsTestBedRender(HomeComponent).then((fixture) => {
                  fixture.detectChanges();
                  const app = fixture.componentInstance;
                  expect(app.title).toBe("Home works!");
              });
            });
        });
    });

And here the result:

JS: NSUTR: downloading http://192.168.10.169:9876/context.json
JS: NSUTR: eval script /base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?be3ff9a5e2d6d748de5b900ac3c6d9603e2942a7
JS: NSUTR: eval script /base/node_modules/karma-jasmine/lib/boot.js?945a38bf4e45ad2770eb94868231905a04a0bd3e
JS: NSUTR: eval script /base/node_modules/karma-jasmine/lib/adapter.js?3098011cfe00faa2a869a8cffce13f3befc1a035
JS: NSUTR: eval script /base/src/tests/test.spec.bundle.js?6e0098824123f3edc2bb093fa874b3fdf268841e
JS: NSUTR: beginning test run
NativeScript / 28 (9; Android SDK built for x86): Executed 1 of 2 SUCCESS (0 secs / 0.545 secs)
NativeScript / 28 (9; Android SDK built for x86): Executed 2 of 2 SUCCESS (0.829 secs / 0.735 secs)
TOTAL: 2 SUCCESS
JS: NSUTR: completeAck
NativeScript / 28 (9; Android SDK built for x86) ERROR
  DisconnectedClient disconnected from CONNECTED state (transport error)
NativeScript / 28 (9; Android SDK built for x86): Executed 2 of 2 SUCCESS (0.829 secs / 0.735 secs)
Paramilitary answered 14/8, 2019 at 16:10 Comment(1)
Hello, first of all thanks for being the only one to leave a comment. I have implemented your suggested changes and they have resulted in the same errors as described. If you are interested I created a branch for you to checkoutFordo
D
-1

Your issue is happening because of these lines.

beforeAll(() => nsTestBedInit()); afterAll(() => { });

Each test file tries to initialize test bed. Make sure that you initialize it in your entry component.

Please refer entry file test-main.ts specified in karma.config.js

Douro answered 20/9, 2019 at 3:20 Comment(4)
I'm not exactly sure what you're referring to as these lines you have specified are not in my question or master branches of either repo linked (I think)? This issue you are correcting is the previous responder's suggested solution. Either way I get the same error. Please correct me if I am mistaken.Fordo
Yes, Sorry If I was not clear I was answering to previous responder. I can take alook at your branch.Douro
I have pushed changes to my branch. I noticed you were trying query element using css selector. I dont think that is possible. But I was able test if component was defined or not. I could not find any way to test template as you would in web based tests.Douro
Thanks! I thought it was clear that I was attempting to use css selectors and I'm not sure why it wouldn't be possible if I am able to write custom methods to traverse and select child elements (using the official repo at least). Furthermore, it seems like the blog post I linked claims "You can now use the de facto unit testing tooling for Angular - TestBed, to writing tests for NativeScript!".Fordo

© 2022 - 2024 — McMap. All rights reserved.