J.P.
J.P.

Reputation: 5754

Using Angular 2's TestComponentBuilder confuses me

I'm working on an Angular 2-rc3 application and I have some unittests set up and they're working, yay! I just don't understand why they have to be written the way they do. And even more amazing, all the examples I see have the same approach. Specifically, these questions are on the top of my list:

  1. Why is the TestComponentBuilder configured in every unittest?

    it('shows list of blog items by default', inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
        return tcb
        .overrideProviders(BlogRoll, [provide(BlogService, {
                useValue: mockBlogService
            })])
            .createAsync(BlogRoll)
            .then((fixture) => {
            // actual test code
        });
    });
    

    That's already seven lines of code extra per unittest and the readability of my code suffers a lot from this. I've tried placing this in a beforeEach():

    beforeEach(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
        console.log('beforeEach');
        return tcb.overrideProviders(BlogRoll, [provide(BlogService, {
                useValue: mockBlogService
            })])
            .createAsync(BlogRoll)
            .then(fixture => {
                // this never gets printed
                console.log('in then:', fixture.componentInstance);
            });
    }));
    

    but Karma doesn't seem to be able to handle the asyncness, everything in the then just doesn't get executed. Is this a bug or is this intended, are we not supposed to do it like this?

  2. Why does the creation of this component need to happen asynchronous? There's a createSync() on the TestComponentBuilder class, can't we use that? Of course I tried it and found out that the function signatures differ: createAsync(rootComponentType: Type) : Promise<ComponentFixture<any>> and createSync(componentFactory: ComponentFactory<C>) : ComponentFixture<C>. Why do we need a component factory here, why don't we need it when creating the component async? // Update: RC4 is out and createSync() now accepts a Type. Great.

My sanity thanks you already!

Upvotes: 2

Views: 2895

Answers (2)

J.P.
J.P.

Reputation: 5754

Angular 2 final has shipped and the TestComponentBuilder class has been replaced by the TestBed, which confuses me a whole lot less.

Upvotes: 3

Edd
Edd

Reputation: 25

  1. The angular2-material tests are nicely organised, and setup TestComponentBuilder in the beforEach, although they do still call createAsync for each test. You can then nest the createAsync call like this:

    describe('Example', () => {
            let fixture;
            let builder: TestComponentBuilder;
    
            beforeEach(injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
                    builder = tcb;
    
                    builder.createAsync(ExampleComponent).then(        
                         fixture = f;
                    });
            });
    
    
            it('Test 1', () => {
                         expect(fixture.componentInstance).not.toEqual(null);
            });
    });
    

Upvotes: 1

Related Questions