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

chore(docs): trigger a detect changes inside the constructor ? #33

Closed
davinkevin opened this issue Jun 17, 2018 · 1 comment
Closed

Comments

@davinkevin
Copy link

Hi,

First of all (and like the last time I saw you), thanks for the job done inside the pro pack and for this libs (and valdemort too).

I'm currently writing slides for VoxxedDays Luxembourg and I think this lib is a must have for me in my presentation. But I'm currently trying to replace the default test written by the CLI with some using the ComponentTester

https://github.com/davinkevin/angular42/blob/master/demo/demo-ngx-speculoos/src/app/app.component.spec.ts

But, I think a complete example project is something missing in this repository.
Examples in compodoc are a bit too short and some ... hide things not trivial for everyone.

In my case, I had to use the method detectChanges(). Without this call, the component template doesn't have its text bindings initialised.

So, without this detectChanges(), I have this error:

Expected element to contain text 'Welcome to app!', but had text ' Welcome to '
	    at UserContext.<anonymous> src/app/app.component.spec.ts:39:26)
	    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke node_modules/zone.js/dist/zone.js:388:1)
	    at AsyncTestZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.AsyncTestZoneSpec.onInvoke node_modules/zone.js/dist/zone-testing.js:713:1)
	    at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke node_modules/zone.js/dist/zone-testing.js:285:1)

For a very simple component :

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

With template :

<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <img width="300" alt="Angular Logo" src="...">
</div>

So, I would like to know if this is a correct way to use the ComponentTester<T> in this kind of test ?

/cc @Neonox31 @dabbid @Yann29

@jnizet
Copy link
Member

jnizet commented Jun 17, 2018

Hi Kevin. Glad you like speculoos!

You got it right. You indeed need a first call to detectChanges(), just as when you use the native ComponentFixture.

We didn't call it by default in the ComponentTester constructor because some component templates can only work once inputs have been set on the component, so it's up to the user to decide when the tester is ready and thus when its view can be rendered for the first time.

Imagine some component with a template like the following:

<p>{{ user.name }}</p>

Where user is an input of the component, which is supposed to always be passed by the parent component.

If the ComponentTester constructor called detectChanges(), then all tests would fail due to an error being thrown because the template evaluation would fail (user being undefined at that time).
So, the proper initialization sequence in the test should instead be

class MyConponentTester extends ComponentTester<MyComponent> {
    super(MyComponent);
    this.componentInstance.user = { name: 'John' };
    this.detectChanges();
}

or, if you prefer doing that outside of the constructor because you want different tests with different inputs:

class MyComponentTester extends ComponentTester<MyComponent> {
    super(MyComponent);
}

describe('tests with John as input', () => {
  let tester: MyComponentTester;
  beforeEach(() => {
    tester = new MyComponentTester();
    tester.componentInstance.user = { name: 'John' };
    tester.detectChanges();
  }

I hope it clarifies things.

Now, I understand your concern about the lack of documentation about this, and I'll try making things clearer.

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

No branches or pull requests

2 participants