[SOLVED] how to fix an error "is not a function" in unit testing angular 11

Issue

I saw this error lot of times but any solution for my problem,

my component :

*/
@Component({
  selector: 'ngx-modal-result-training',
  templateUrl: './modal-result-training.component.html',
  styleUrls: ['./modal-result-training.component.scss'],
})
export class ModalResultTrainingComponent implements OnInit {
  @Input() results: IAttempt;
  @Input() training: ITraining;
  public validated = false;
  public opinionForm: FormGroup;
  public selectedStars = 0;
  public hasAlreadyComment = true;
  public percentageScore: number;

  constructor(
    private opinionsService: OpinionsService,
    private userService: UserService,
    private ref: NbDialogRef<ModalResultTrainingComponent>,
    private router: Router,
    private toastrService: NbToastrService,
    private translateService: TranslateService,
    private dialogService: DialogService
  ) {}

  public ngOnInit(): void {
    this.dialogService.refs.push(this.ref);
    this.percentageScore = Math.floor(this.results.score);
    this.validated = this.percentageScore >= this.training.minimalScore;

    this.checkUserOpinion();
    this.initForm();
  }

My test :


const training = {
  id: 'ZGtz6yrEemCNTo5KAytu',
  refProject: 'JGvD1faO8L2vWb66BQ87',
  publicationDate: new Date(),
  version: 1,
  name: 'My project',
  groups: [],
  category: '',
  description: '',
  minimalScore: 80,
  previewPNG: '',
  level: 5,
  gain: 5,
  fromDate: new Date(),
  toDate: new Date(),
  totalSlides: 20,
  stars: 3,
  averageStars: 4,
  comments: 15,
  groupsHistoric: [],
} as ITraining;

const trainingResults = {
  id: 'ZDqzqg',
  version: 1,
  trainingID: 'xSOvDC6vpZTzVqXy5owQ',
  userID: 'qdZDZDqg',
  groupsIDs: [],
  date: new Date(),
  time: 10,
  score: 10,
  validated: true,
  finished: true,
  currentStep: 4,
} as IAttempt;

fdescribe('ModalResultTrainingComponent', () => {
  let component: ModalResultTrainingComponent;
  let fixture: ComponentFixture<ModalResultTrainingComponent>;
  let mockOpinionsService =  jasmine.createSpyObj('OpinionService', ['addOpinion']);
  let mockDialogService = jasmine.createSpyObj('DialogService', ['closeAll', 'refs', 'push']);
  let mockUserService = jasmine.createSpyObj('UserService', ['user$']);
  let mockRouter = jasmine.createSpyObj('Router', ['navigate']);
  let mockToastrService = jasmine.createSpyObj('NbToastrService ', ['success']);
  let mockTranslateService = jasmine.createSpyObj('TranslateService ', ['instant']);
  let nbAclService = jasmine.createSpyObj('NbAclService' , ['allow', 'can', 'register', 'setAccessControl']);
  let nbDialogRef = jasmine.createSpyObj('NbDialogRef', ['push']);

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ModalResultTrainingComponent],
      providers: [
        {provide :  Router, useValue: mockRouter},
        {provide :  OpinionsService, useValue: mockOpinionsService},
        {provide :  UserService, useValue: mockUserService},
        {provide :  DialogService, useValue: mockDialogService},
        {provide :  NbToastrService, useValue: mockToastrService},
        {provide :  TranslateService, useValue: mockTranslateService},
        {provide :  NbDialogRef, useValue: nbDialogRef},
        EntityService,
        {provide : NbAclService, useValue : nbAclService},
        ],
      imports: [
        FireModule,
        RouterModule.forRoot([]),
        NbThemeModule.forRoot(),
        NbDialogModule.forRoot(),
        NbAuthModule.forRoot(),
        TranslateModule.forRoot(),
      ],
      schemas: [NO_ERRORS_SCHEMA],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ModalResultTrainingComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    mockOpinionsService = TestBed.inject(OpinionsService);
    mockUserService = TestBed.inject(UserService);
    mockDialogService = TestBed.inject(DialogService);
    mockRouter = TestBed.inject(Router);
    mockToastrService = TestBed.inject(NbToastrService);
    mockTranslateService = TestBed.inject(TranslateService);
    nbAclService = TestBed.inject(NbAclService);
    nbDialogRef = TestBed.inject(NbDialogRef);
    component.training = training;
    component.results = trainingResults;


  });

  it('should create', () => {
    //expect(component.results.validated).toBeTrue();
    expect(component).toBeTruthy();
  });
});

I don’t understand why I got this error : " TypeError: this.dialogService.refs.push is not a function"

I try to replace useClass instead of useValue but I had unreachable knowing is angular 11.
I did lot of research but I found anything.

thanks to all for help

Solution

When you do:

let mockDialogService = jasmine.createSpyObj('DialogService', ['closeAll', 'refs', 'push']);

You’re saying that there is a refs method on DialogService that I would like to mock but refs is not a method, it’s an instance variable.

To fix it, I would do this:

let mockDialogService = jasmine.createSpyObj('DialogService', ['closeAll']);
mockDialogService.refs = [];

Now we attached a refs property with an empty array and hopefully you shouldn’t see that error anymore. We assigned an empty array so .push will work.

Answered By – AliF50

Answer Checked By – Mildred Charles (BugsFixing Admin)

Leave a Reply

Your email address will not be published.