Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ng5 Karma Jasmine test renders component instead of result page

Let's say i have a very simple 'create' unit test, kind that ng cli generates for you:

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent],
      imports: [
        HttpClientTestingModule,
        FormsModule,
        RouterTestingModule.withRoutes([{ path: 'home', redirectTo: '/' }])
      ],
      providers: [SomeService1, SomeService2, { provide: SomeService3, useValue: {} }],
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Now when i run this test like so ng test --browser=Chrome instead of looking at Karma results page, i am looking at my component.

My CLI version is 1.6.3, Karma 1.7.1, Angular 5.2.0, OS macOS.

Update My browser is captured, karma loads, tests run but instead of karma results i see my full-screen component because it's css overlays their results. If i find the div and delete it in the DOM, i can see Karma results.

I was just expecting Angular to remove that node.

like image 849
zaitsman Avatar asked Jan 28 '18 23:01

zaitsman


People also ask

What is the difference between karma and Jasmine?

Jasmine can be classified as a tool in the "Javascript Testing Framework" category, while Karma is grouped under "Browser Testing". "Can also be used for tdd " is the primary reason why developers consider Jasmine over the competitors, whereas "Test Runner" was stated as the key factor in picking Karma.

Does karma use Jasmine?

We can run Jasmine tests in a browser ourselves by setting up and loading a HTML file, but more commonly we use a command-line tool called Karma. Karma handles the process of creating HTML files, opening browsers and running tests and returning the results of those tests to the command line.

What is the use of angular karma in testing?

Karma is an open-source test runner for JavaScript created by the angular team. Karma can be easily integrated into your project and makes it easy to execute tests using CLI. Karma is useful for executing the tests on browsers, other devices like phones, tablets. Karma can be configured with different test frameworks including Jasmine, Mocha, Quit.

What is Jasmine testing framework?

Jasmine is the framework we are going to use to create our tests. It has a bunch of functionalities to allow us the write different kinds of tests. karma. Karma is a task runner for our tests. It uses a configuration file in order to set the startup file, the reporters, the testing framework, the browser among other things.

What is the default browser for Karma testing?

By default it is chrome but you can install and use other browser launchers. The angular-cli configuration of karma uses the file “test.ts” as the entry point of the tests for the application. Let’s take a look to that file; We have a lot of things going on here.

What is the best way to test AngularJS components?

Angular provides a good boilerplate for writing testings with both Jasmine framework and Karma test runner. Using the Test Wrapper pattern in your tests is a good way to fully test the life cycle of a component and easily test how changes in a parent will effect the component you are testing.


1 Answers

I am not really sure why the DOM compilation of the component stays after the test ends, but I noticed it happens only for the last test that ran. If you can add another component test that also compiles a component but doesn't add a full-screen component, the previous one is correctly removed. So, simply adding more tests could be the easiest solution.

But if that's not enough, here goes two possible solutions:

1. Don't compile it

If your tests don't involve verifying the resulting DOM, you can simplify the arrangement of your test by using the component directly.

describe('MyComponent', () => {
  TestBed.configureTestingModule({
    // declarations: [MyComponent],
    imports: [
      HttpClientTestingModule,
      FormsModule,
      RouterTestingModule.withRoutes([{ path: 'home', redirectTo: '/' }]),
    ],
    // 1. Add the component as a provider.
    providers: [MyComponent, SomeService1, SomeService2, { provide: SomeService3, useValue: {} }],
    schemas: [NO_ERRORS_SCHEMA],
  });

  it('should do thing #1', () => {
    // 2. Test it like you would test a service.
    const comp = TestBed.get(MyComponent);
    expect(comp.value).toBe(false, 'off at first');
    comp.doThing1();
    expect(comp.value).toBe(true, 'on after click');
    comp.doThing1();
    expect(comp.value).toBe(false, 'off after second click');
  });

  it('should do thing #2', () => {
    const comp = TestBed.get(MyComponent);
    expect(comp.value2).toMatch(/is off/i, 'off at first');
    comp.doThing2();
    expect(comp.value2).toMatch(/is on/i, 'on after clicked');
  });
});

More info here.

2. Remove it from DOM

If you do need to test the DOM, the only workaround I have found is to explicitly remove the HTML element after finishing the tests.

  afterEach(() => {
    if (fixture.nativeElement && 'remove' in fixture.nativeElement) {
      (fixture.nativeElement as HTMLElement).remove();
    }
  });
like image 153
Ruluk Avatar answered Nov 15 '22 19:11

Ruluk