2

I'm developing a Date Range picker component in Angular and having difficulty testing if input values are bad.

My ngOnInit() does a check for min/max date values.

When I attempt to write a test for this case

Jasmine returns:

Expected function to throw RangeError, but it threw TypeError: Cannot read property 'ngZone' of undefined.

Researching S.O. posts, led me to create a mock NgZone class and provide that in the TestBed, which simply leads to more problems such as "subscribe is undefined".

I thought this might be due to an EventEmitter, but I've tried removing that, and I receive the same errors.

First, how can I resolve the NgZone error? There are a few S.O. posts on this topic, but I seem to be coming up short.

Second, how can I properly test that my ngOnInit() behaves as expected if bad values are passed in?

Update

Even through I had isolated my input validation function, I still wasn't able to check if that function threw an error. Instead, I had to check detectChanges(), which is the function that invoked everything else:

expect(() => fixture.detectChanges()).toThrow();
3
  • First question there is several ways to mock if you mean to just mock the NgZone service inside a component? Second question, do you want to test if code is simply running in that lifecycle? Commented Nov 14, 2018 at 6:12
  • @Lucho I really just want to be able to test that ngOnInit() is behaving as expected. If I don't have to mock NgZone to accomplish that, I'll be just as happy. Commented Nov 14, 2018 at 12:45
  • Check posted answer, does it help you? Commented Nov 17, 2018 at 16:11

1 Answer 1

3

The NgZone service is used to reach Api’s for supporting to run code inside and outside ZoneJS space. However if you find it useful in your test to use it you can create an instance of the service by using:

let ngService = Testbed.get(NgZone)

If your purpose to test the lifecycle ngOnInit() of the component, Angular has provided tools for this in the Testbed API by using ComponentFixture where you have control of generating a changedetection in order to trigger ngOnInit like so:

describe('tests', () => {

  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [ ],
        declarations: [ MyComponent ],
    }).compileComponents();
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;

  }));


  it('simple test', async(() => {
    fixture.detectChanges(); // triggers cd and passes through component lifecycle ngOnInit

  }));

});
Sign up to request clarification or add additional context in comments.

4 Comments

Changing when .detectChanges() is invoked seems to have cleared up the NgZone error, however, I'm still not able to test the exception is thrown. I isolated my input checks to a separate method, and that doesn't work either. Any ideas?
@Brandon, is your github updated? If not update your post example with it() test and the method you are using
I got it figured out. Instead of expecting .validateOptionDates to trow, I had to switch it to .fixture.detectChanges
I'm marking your answer as correct as moving the change detection is what fixed the NgZone error which was my original question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.