X Tutup
The Wayback Machine - https://web.archive.org/web/20200628001024/https://github.com/angular/angular/issues/37646
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input value is an empty string in Jasmine Tests using an combined element, attribute Component Selector #37646

Open
riede opened this issue Jun 19, 2020 · 2 comments

Comments

@riede
Copy link

@riede riede commented Jun 19, 2020

🐞 bug report

Description

I've got a component with some inputs. Some of them are optional but the input config is required to use the component. Therefore I defined a component selector that has an element part and an attribute part (e.g. app-my-component[config]). Now I always need to pass a config into the component if I want to use it. Great! I started the app with ng serve and everything works fine. So far so good...

While writing the component tests I'm coming in trouble. I set the config in the beforeEach block where the component fixture is also created. However the required input attribute config is always an empty string when I called fixture.detectChanges().

Here is the Test-File of the minimal Reproduction I wrote that shows exactly the behaviour.

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ TestComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(TestComponent);
    component = fixture.componentInstance;
    component.requiredInput = { anyKey: 'anyValue'};
    fixture.detectChanges();
  });

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

  it('should not fail', () => {
    const expectedResult: RequiredInput = { anyKey: 'anyValue' };
    expect(component.requiredInput).toEqual(expectedResult); // <-- this expectation fails
  });
});

Removing the attribute part of the selector solves the problem. But that is no way.

🔬 Minimal Reproduction

I've created a minimal GitHub repository with the reproduction of the issue. I used Angular 8 for the reproduction repository because my main project is still using Angular 8, too

🌍 Your Environment

Angular Version:




Angular CLI: 8.3.26
Node: 10.19.0
OS: darwin x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.803.26
@angular-devkit/build-angular      0.803.26
@angular-devkit/build-ng-packagr   0.803.26
@angular-devkit/build-optimizer    0.803.26
@angular-devkit/build-webpack      0.803.26
@angular-devkit/core               8.3.26
@angular-devkit/schematics         8.3.26
@angular/cli                       8.3.26
@ngtools/webpack                   8.3.26
@schematics/angular                8.3.26
@schematics/update                 0.803.26
ng-packagr                         5.7.1
rxjs                               6.5.5
typescript                         3.5.3
webpack                            4.39.2

@jnizet
Copy link
Contributor

@jnizet jnizet commented Jun 20, 2020

Not sure if it's a bug or a feature (I'll let better specialists decide about that).

But the typical way of testing a component that requires inputs is to actually pass inputs the way they're supposed to be passed, with a test such as this one:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TestComponent, RequiredInput } from './test.component';
import { Component } from '@angular/core';
import { By } from '@angular/platform-browser';

@Component({
  template: '<app-test [requiredInput]="input"></app-test>'
})
class FixtureComponent {
  input!: RequiredInput;
}

describe('TestComponent', () => {
  let fixtureComponent: FixtureComponent;
  let component: TestComponent;
  let fixture: ComponentFixture<FixtureComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ TestComponent, FixtureComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(FixtureComponent);
    fixtureComponent = fixture.componentInstance;
    component = fixture.debugElement.query(By.directive(TestComponent)).componentInstance;
    fixtureComponent.input = { anyKey: 'anyValue'};
    fixture.detectChanges();
  });

  it('should not fail', () => {
    const expectedResult: RequiredInput = { anyKey: 'anyValue' };
    expect(component.requiredInput).toEqual(expectedResult);
  });
});
@mhevery mhevery added the comp: forms label Jun 22, 2020
@ngbot ngbot bot added this to the needsTriage milestone Jun 22, 2020
@riede
Copy link
Author

@riede riede commented Jun 23, 2020

Not sure if it's a bug or a feature (I'll let better specialists decide about that).

But the typical way of testing a component that requires inputs is to actually pass inputs the way they're supposed to be passed, with a test such as this one:

This "workaround" works for me. Thanks!

I think the main problem (I described) is that the component is created by the TestBed without any parent that gives the input into the component itself. So it could be a way to pass an argument object while creating the component fixture - e.g.:

beforeEach(() => {
  fixture = TestBed.createComponent(TestComponent, {
    requiredInput: { anyKey: 'anyValue'}
  });
  component = fixture.componentInstance;
  fixture.detectChanges();
});

In this case each attribute represents a value the TestBed sets to the same named input of the component as a default value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.
X Tutup