1

I am new to jasmine. Here I am trying to run a test case but it fails with the following error:

Expected spy navigate to have been called with [ [ 'home/blah/bloo' ] ] but actual calls were [ [ 'home' ] ].

Error: Expected spy navigate to have been called with [ [ 'home/blah/bloo' ] ] but actual calls were [ [ 'home' ] ].
at stack (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?916005cc407925f4764668d61d04888d59258f5d:1640:17) [ProxyZone]
at buildExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?916005cc407925f4764668d61d04888d59258f5d:1610:14) [ProxyZone]
at Spec.expectationResultFactory (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?916005cc407925f4764668d61d04888d59258f5d:655:18) [ProxyZone]
at Spec.addExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?916005cc407925f4764668d61d04888d59258f5d:342:34) [ProxyZone]
at Expectation.addExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?916005cc407925f4764668d61d04888d59258f5d:599:21) [ProxyZone]
at Expectation.toHaveBeenCalledWith (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?916005cc407925f4764668d61d04888d59258f5d:1564:12) [ProxyZone]
at Object.<anonymous> (http://localhost:9876/base/src/test.ts?efc7a0f996ccb0dbc70e4ff35bdebac4252e6864:70856:43) [ProxyZone]
at AsyncTestZoneSpec.Array.concat.AsyncTestZoneSpec.onInvoke (http://localhost:9876/base/src/test.ts?efc7a0f996ccb0dbc70e4ff35bdebac4252e6864:131017:39) [ProxyZone]
at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (http://localhost:9876/base/src/test.ts?efc7a0f996ccb0dbc70e4ff35bdebac4252e6864:131703:39) [ProxyZone]
at runInTestZone (http://localhost:9876/base/src/test.ts?efc7a0f996ccb0dbc70e4ff35bdebac4252e6864:22805:25) [ProxyZone]
at Object.<anonymous> (http://localhost:9876/base/src/test.ts?efc7a0f996ccb0dbc70e4ff35bdebac4252e6864:22744:13) [ProxyZone]

Component code:

@Component({
  selector: 'app-component-name',
  templateUrl: './component-name.component.html'
})
export class ComponentNameComponent extends Class implements AfterViewInit {

  @ViewChild('id') id: ElementRef;
  private context = 'Blah';
  user: User;
  errorMessage = '';

  constructor(private userService: UserService,
              private router: Router,) {
    super();
    this.user = new User('');
  }


  responseHandler = (userResponse) => {

    const userObject: { resultCode: number, user: User, permissions: Object }
      = JSON.parse(userResponse.body);
    const resultCode = +userObject.resultCode;
    if (resultCode === 0) {
      this.userService.setUser(userObject.user);

      if (condition) {
        this.router.navigate(['home', 'blah', 'foo', 'bar']);
      } else {
        this.router.navigate([this.router.url]);
      }
    } else if (resultCode === 1) {
      this.errorMessage = 'Error Message';
    } else {
      this.errorMessage = 'Standard Error Message';
    }
  }

  ngAfterViewInit() {
    this.id.nativeElement.focus();
  }
}

Jasmine code:

describe('ComponentNameComponent', () => {

  let fixture;
  let component;
  let response: any = {};
  let responseBody;

  let router: any = {};

  class MockUserService extends UserService {

    setUser() {
    }
  }


  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [
        ComponentNameComponent
      ],
      imports: [
        FormsModule,
        HttpModule,
        RouterTestingModule.withRoutes([])
      ],
      providers: [
        {provide: Router, useValue: router},
        {provide: UserService, useClass: MockUserService}
      ]
    });
    TestBed.compileComponents();

    fixture = TestBed.createComponent(ComponentNameComponent);
    component = fixture.debugElement.componentInstance;
    response = {};
    router = {
      navigate: jasmine.createSpy('navigate'),
      url: 'home'
    };
    responseBody = {
      resultCode: '0',
      user: {
        userName: 'test'
      },
    };
  });

  /* Test 1: This test runs successfully */

  it('should handle result code 0 with navigation to home ', async(()
    => {
    const userService = spyOn(fixture.debugElement.injector.get(UserService), 'setUser');
    component.user = {userName: 'test'};
    response.body = JSON.stringify(responseBody);

    fixture.detectChanges();
    component.responseHandler(response);
    expect(userService).toHaveBeenCalled();
    expect(component.router.navigate).toHaveBeenCalledWith(['home']);
  }));

  /* Test 2: This test fails */

  it('should handle result code 0 with navigation to package basic', async(() => {
    const userService = spyOn(fixture.debugElement.injector.get(UserService), 'setUser');
    router.url = 'home/blah/bloo';
    component.user = {userName: 'test'};

    response.body = JSON.stringify(responseBody);

    fixture.detectChanges();
    component.responseHandler(response);
    expect(userService).toHaveBeenCalled();

    console.log(router.url); // Proper value is displayed - 'home/blah/bloo'        

    expect(component.router.navigate).toHaveBeenCalledWith([router.url]);
  })); // This is called with previous value of 'home'

  /* Test 3: This test runs successfully */

  it('should handle result code 0 with condition by navigating to foo bar', async(() => {
    const userService = spyOn(fixture.debugElement.injector.get(UserService), 'setUser');
    component.user = {userName: 'test'};

    response.body = JSON.stringify(responseBody);

    fixture.detectChanges();
    component.responseHandler(response);
    expect(userService).toHaveBeenCalled();
    expect(component.router.navigate).toHaveBeenCalledWith(['home', 'blah', 'foo', 'bar']);
  }));

  /*Test 4: This test runs successfully */

  it('should handle result code 1', async(() => {
    const userService = spyOn(fixture.debugElement.injector.get(UserService), 'setUser');

    component.user = {userName: 'test'};
    component.router.navigate.calls.reset();

    responseBody.resultCode = '109';
    response.body = JSON.stringify(responseBody);

    fixture.detectChanges();
    component.responseHandler(response);
    expect(userService).not.toHaveBeenCalled();
    expect(component.router.navigate).not.toHaveBeenCalled();
  });

});

Please tell me what am I doing wrong here. Thanks in advance.

Arjun Varrier
  • 167
  • 1
  • 4
  • 11
  • You're using an undefined variable `condition`. You're also passing {} as the router service when creating the testing module, but then replace replace that actual value, used by angular, by another object in your test. So the router used by your test is not the same object as the one used by angular. – JB Nizet Nov 03 '17 at 07:10
  • I can't provide the actual code. Hence I have made certain changes. Here `condition` is not a variable, but some random condition based on which the user would be redirected to appropriate path – Arjun Varrier Nov 03 '17 at 07:19
  • You mean the way you create the testing module, and reinitialize the router is completely different in your actual code? If so, you're asking us to find a bug in code A by showing is code B. Not doable. – JB Nizet Nov 03 '17 at 07:21
  • If you can make the time, I suggest creating a working plunker [MVCE](https://stackoverflow.com/help/mcve). Redacting code makes it more difficult for us to know if it's an error in your implementation or the code edits. Creating the MVCE is also a good way to better understand the problem and strengthens troubleshooting skills. – stealththeninja Nov 03 '17 at 07:25
  • @JBNizet No. the variable names, function names, component names have been changed and a few lines have been removed. – Arjun Varrier Nov 03 '17 at 07:29
  • @stealththeninja sure i will create a plunkr and provide the link – Arjun Varrier Nov 03 '17 at 07:29
  • Then re-read my comment. The part about the router. You provide router A to the module, and then assign B to the router variable and use that in your test. So your test changes the state of router B, but angular uses router A. – JB Nizet Nov 03 '17 at 07:31
  • I think you would need to mock the router with RouterTesting module. Refer: https://stackoverflow.com/questions/39791773/angular-2-unit-testing-with-router – ajinkya udgirkar Nov 03 '17 at 09:11

0 Answers0