Home > Back-end >  Unit Testing for provider which includes service with Replay Subject cannot read undefined of pipe
Unit Testing for provider which includes service with Replay Subject cannot read undefined of pipe

Time:10-12

I am trying to cover a provider with Unit Test which includes a map at return with pipe. But somehow the method is not a function says jasmine.

The provider it is used for Hotjar module.

This is my test.

fdescribe('UserRolesProvider', () => {
  let service: UserRolesProvider;
  let userServiceSpy: { onUserEvent: jasmine.Spy };

  beforeEach(waitForAsync(() => {
    userServiceSpy = jasmine.createSpyObj('UserService', ['onUserEvent']);

    TestBed.configureTestingModule({
      providers: [UserRolesProvider, { provide: UserService, useValue: userServiceSpy }],
    });
    service = TestBed.inject(UserRolesProvider);
  }));
  it('should have a service instance', () => {
    expect(service).toBeDefined();
  });

  it('showContents should return true for an Admin Role', (done) => {
    const attributes = {
      roles: ['ROLE_ADMIN'],
    };
    service.getUserAttributes().subscribe((state) => {
      expect(state.attributes).toEqual(attributes);
      done();
    });
    spyOn(userServiceSpy, 'onUserEvent').and.returnValue(of(attributes));
    service.getUserAttributes(); // invoke after
    expect(service.getUserAttributes).toHaveBeenCalled();
  });
});

This is my TS

@Injectable({
  providedIn: 'root',
})
export class UserRolesProvider implements HotjarUserAttributesLoader {
  constructor(private userService: UserService) {}

  getUserAttributes(): Observable<HotjarUserAttributes> {
    return this.userService.onUserEvent().pipe(
      map((user) => {
        return {
          id: user.id,
          attributes: {
            roles: user.roles,
          },
        };
      })
    );
  }
}

And this is the user Service.

 private userEvent$ = new ReplaySubject<User>(1);

 onUserEvent(): ReplaySubject<User> {
    return this.userEvent$;
  }

HotJarUserAttributes it is an interface

export interface HotjarUserAttributes {
    id: string;
    attributes: any;
}

CodePudding user response:

You have spied the dependency using the below line:

userServiceSpy = jasmine.createSpyObj('UserService', ['onUserEvent']);

but you have not specified what this observable will return. As I can see you are returning an object of type user which has two properties id and roles in your component code. You can fix the issue by returning same type in test case as well. Just add the below line after your spy creation.

const returnedObject: HotjarUserAttributes = {
  id: '1',
  attributes: { roles: [1, 2] },
}

userServiceSpy.onUserEvent.and.returnValue(of(returnedObject))
  • Related