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

Unit Testing: Set Up Question #47

Closed
2 of 9 tasks
lcecil opened this issue Oct 18, 2018 · 3 comments
Closed
2 of 9 tasks

Unit Testing: Set Up Question #47

lcecil opened this issue Oct 18, 2018 · 3 comments
Labels
pkg: store Related to the store package

Comments

@lcecil
Copy link

lcecil commented Oct 18, 2018

Posting this here, as well as in the old repo

This is a...

  • feature request
  • bug report
  • usage question

What toolchain are you using for transpilation/bundling?

  • @angular/cli
  • Custom @ngTools/webpack
  • Raw ngc
  • SystemJS
  • Rollup
  • Other

Environment

NodeJS Version: 8.11.2
Typescript Version: 2.7.2
Angular Version: 6.0.9
@angular-redux/store version: 9.0.0
@angular/cli version: (if applicable)

Description

I've read through the unit test examples, and believe that I have my set up correct. However, it seems like my mock instance is not being substituted for the real NgRedux that is injected.

Simplified Code

Component

  export class MyComponent implements OnInit {
    state: ApplicationState;
    constructor(private ngRedux: NgRedux<ApplicationState>) {}

    ngOnInit() {
       this.state = this.ngRedux.getState();
    }
  }

Unit Test

  // In the main describe...
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ NgReduxTestingModule ],
      declarations: [ MyComponent ],
      schemas: [ NO_ERRORS_SCHEMA ]
    })
    .compileComponents();
    MockNgRedux.reset();
   }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
  
  it('should set the initial state object', () => {
    const spy = spyOn(MockNgRedux.mockInstance, 'getState');
    expect(spy).toHaveBeenCalled();
  });

Error Message

When I run my tests with the code above, I get the message:
Expected spy getState to have been called.

Am I missing something in my set up?

@smithad15
Copy link
Member

@wtho Can you confirm what the solution to this was if a solution was found?

@smithad15 smithad15 added the pkg: store Related to the store package label Jan 8, 2019
@wtho
Copy link
Contributor

wtho commented Jan 8, 2019

Hey!

When installing the spy, the testbed was already setup, and the component compiled and instantiated and the constructor already executed. The component lifecycle hooks, such as ngOnInit are not called yet, which is great, so we can do things like setting up the spy. But it also will not be called by the testbed automatically, as it does not know, if the lifecycles are required for tests or not.

This means you have to call them in the test itself. You can call the lifecycle hooks on your own or make the test environment call them, e. g. an execution of fixture.detectChanges() is enough to trigger ngOnInit on the component.

I personally prefer to call the lifecycle hooks directly, as anyone can immediately see in your test, what you are testing. Modify your test in this way:

  it('should set the initial state object', () => {
    const spy = spyOn(MockNgRedux.mockInstance, 'getState');
    // alternatively call fixture.detectChanges(); here
    component.ngOnInit();
    expect(spy).toHaveBeenCalled();
  });

Let us know if this solved your problem and feel free to close the issue if it did.

Cheers!

@lcecil
Copy link
Author

lcecil commented Jan 8, 2019

Hi.

Thanks for the reply, that helped. I played around with things and got it to work with this setup:

  // In the main describe...
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ NgReduxTestingModule ],
      declarations: [ MyComponent ],
      schemas: [ NO_ERRORS_SCHEMA ]
    })
    .compileComponents();
    MockNgRedux.reset();
   }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    ngRedux = MockNgRedux.getInstance(); // mockInstance looks like it's deprecated
    spyOn(ngRedux, 'getState');
    fixture.detectChanges();
  });
  
  it('should set the initial state object', () => {
    expect(ngRedux.getState).toHaveBeenCalled();
  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: store Related to the store package
Development

No branches or pull requests

3 participants