Angular - failure to detect function execution by spy

I've been trying to test a feature module, but I'm facing some difficulties. The last test is failing because the spy isn't detecting that the method is being called, even when I move the

this.translate.use(this.currentLanguage.i18n)
call outside of the subscribe block.

This is the code for the feature component:

export class LanguagesComponent implements OnDestroy, OnInit {

  public languages = [
    {
      id: '0',
      name: this.translate.stream('LANGUAGES.SWEDISH'),
      i18n: 'sv',
      flag: {
        src: './assets/img/sv.svg'
      }
    },
    {
      id: '1',
      name: this.translate.stream('LANGUAGES.ENGLISH'),
      i18n: 'en',
      flag: {
        src: './assets/img/en.svg'
      }
    }
  ];

  public currentLanguage: any;

  private storageSubscription: Subscription;

  constructor(
    private cs: ClientStorage,
    private notifications: NotificationsApi,
    private router: Router,
    private translate: TranslateService
  ) {}

  ngOnInit() {

    const storedLanguage: any = this.cs.getItem(AppConstants.currentLanguage);

    this.currentLanguage = FindObjectByQuery(this.languages, 'i18n', storedLanguage);

    // Listen for changes in language from sources other than this component
    this.storageSubscription = this.cs.logger$
      .filter(data => data && data.key === AppConstants.currentLanguage)
      .subscribe((currentLanguage: any) => {

        if (currentLanguage) {

          this.currentLanguage = FindObjectByQuery(this.languages, 'i18n', currentLanguage.value);

          // Set the current language to use
          this.translate.use(this.currentLanguage.i18n);
        }
      }
    );
  }

  ngOnDestroy() {
    this.storageSubscription.unsubscribe();
  }

  selectLanguage(language: any): void {

    this.cs.setItem(AppConstants.currentLanguage, language.i18n);

    this.router.navigate(['dashboard']);

    this.notifications.newNotification({message: this.translate.instant('NOTIFICATIONS.LANGUAGES.CHANGED'), theme: 'success'});
  }
}

These are my current tests:

describe('[UNIT] LanguagesComponent', () => {

  let component: LanguagesComponent;
  let fixture: ComponentFixture<LanguagesComponent>;
  let translate: Location;

  beforeEach(() => {

    TestBed.configureTestingModule({
      imports: [
        ModuleImports
      ],
      providers: [
        TranslateService
      ],
      schemas: [NO_ERRORS_SCHEMA],
      declarations: [LanguagesComponent, DummyComponent]
    });

    fixture = TestBed.createComponent(LanguagesComponent);
    component = fixture.componentInstance;
    translate = TestBed.get(TranslateService);

    // Ensure ngOnInit runs
    fixture.detectChanges();
  });

  it('should create the component', async(() => {
    expect(component).toBeTruthy();
  }));

  it('should have a current language when the component has loaded', () => {
    expect(component.currentLanguage).toBeTruthy();
  });

  it('should have the necessary properties in the current language object', () => {

    const currentLanguage = component.currentLanguage;

    expect(currentLanguage.id).toBeTruthy();
    expect(currentLanguage.name).toBeTruthy();
    expect(currentLanguage.i18n).toBeTruthy();
    expect(currentLanguage.flag.src).toBeTruthy();
  });

  it('should trigger the use method of TranslateService with the current language i18n value', () => {

    const spy = spyOn(translate, 'use').and.callThrough();

    expect(spy).toHaveBeenCalledWith(component.currentLanguage.i18n);
  });
});

Answer №1

During your test scenario, you set up a spy but then attempted to verify a call immediately afterwards. However, no call was recorded.

To address this issue, there are two possible solutions:

  1. Ensure that you place the spyOn before making any changes with fixture.detect in the beforeEach block.
  2. After creating the spy, activate the appropriate method that should trigger the expected call. In this case, make sure to execute fixture.detectChanges.

Please note: I have not checked your tests for any other issues aside from the main problem of the missing call between spy creation and usage.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unknown provider error in Angular Jasmine mock testing

I am currently facing an issue with two spec files not working well together. It is surprising to me that one spec file could affect another, as I did not expect this behavior. The tools I am using for automation are Jasmine and Karma, with tests automate ...

Encountering Error with NodeJS Typescript: Issue with loading ES Module when running sls offline command

I have come up with a unique solution using NodeJS, Typescript, and Serverless framework to build AWS Lambdas. To debug it locally in VS Code, I use the serverless-offline library/plugin. You can find my project on GitHub here However, when I run the comm ...

The type Observable<any> cannot be assigned to Observable<any> type

I am currently working with angular 5 and ionic 3. I have defined an interface: export interface IAny { getDataSource: Observable<any>; } Components that implement this interface must have the following method: getDataSource () { return ...

Issues encountered while transitioning from Angular 2 to 4 using npm

I am facing a challenge in upgrading Angular 2 to Angular 4 using npm. I have tried running "npm update --save" in the terminal, but unfortunately, my package.json does not reflect the latest Angular 4 version and remains unchanged. Can someone please ad ...

Stack the labels of separate datasets on top of each bar in a bar chart using Chartjs: How can this be achieved?

chart.js 4.4.2 chartjs-plugin-datalabels I am aiming to achieve this effect const chartCtr = document.querySelector('#temp-chart1') as HTMLCanvasElement; new Chart(chartCtr, { type: 'line', plugins: [ChartDataLabels], opt ...

Trying to assign a value to a key on an object that is supposed to be unchangeable and has been locked in place. [ Angular2 + React Native ]

Currently, I am developing a mobile app using Angular2 + React Native. I encountered an issue when trying to run the following code: <Text [styleSheet]="styles.button" opacityFeedback (tap)="showMore=!showMore" testID="Show_More"> {{showMore ? & ...

Interacting between Angular Child and Parent components

I am facing an issue where I am trying to emit an event from a child component and display it in the parent HTML, but it doesn't seem to be working. Below is my code: ParentComponent.ts @Component({ selector: 'app-parent', templateUrl: ...

Storing Array Data in Ionic Using Native Storage - A Step-by-Step Guide

I want to implement a feature in my app where I can store translation history using Ionic Native Storage. Every time a word is translated, the translation action (date, translated word) will be saved in the storage. Then, when I navigate to the history pag ...

Trigger a (click) or (keyup) event in Angular 4+ only when the value meets the specified pattern

Here is the HTML code snippet. The keyup event will only be triggered if the value in the input field matches the specified pattern. <input (keyup)="checkPatternMatch(ProjectName)" type="text" #ProjectName="ngModel" name="pro-name" class="form-control" ...

Is it possible to track when a user switches to a different component in Angular?

I'm looking to set up a confirmation popup when the user attempts to navigate to a different page. I've come across information about hostListener and canActivate, but I'm not exactly sure how to begin! Any guidance would be greatly apprecia ...

How to transfer the returned value from an anonymous callback function to the `this` keyword in an ionic2 angular4 project

Currently, I am utilizing a custom geolocation provider that operates asynchronously. It takes approximately 3-5 seconds to retrieve the user's location. Using an anonymous callback function works fine when I console.log the results and view the value ...

"Curious why the change event doesn't trigger when selecting an option that is already selected

Angular reactive forms are causing an issue where the change method for select field does not fire when selecting an already selected option. You can view an example of this behavior at the following link: https://stackblitz.com/edit/angular-2e1cvz. In t ...

"Obtaining subnet identification using the name or CIDR: A step-by-step

I am seeking help on retrieving the subnet id based on subnet name or cidr in order to deploy a nat gateway. Can someone provide guidance on how to obtain the subnet id? Alternatively, does anyone have any best practices for utilizing typescript function ...

What is the proper way to reference a computed symbol that has been inherited as a function in an extended class

As a newcomer to Typescript, my understanding of the code might be lacking. I am currently working with the Klasa framework, which is built on top of Discord bot framework using Discord.js. The framework recently introduced plugin functionality and there a ...

Navigating to a precise element within a page in Angular with flawless redirection

I recently encountered an issue where I had to add a span element with a specific ID in my HTML code to ensure that clicking on the Reply button would navigate to it. However, this modification was only necessary for the last element on the page. While the ...

The call to the Angular service has no matching overload between the two services in Typescript with 13 types

I encountered an error while creating a new Angular project following a tutorial, and I'm seeking assistance to understand it. The error message reads: "No overload matches this call. Overload 1 of 5... Type 'Object' is missing the followi ...

Develop a customized configuration module for managing ESLint, Prettier, and resolving import issues efficiently

Currently, I am developing a configuration npm module for my personal project. This repository includes Prettier, ESLint, tsconfig, and other tools that I have set up. You can find my configuration tools repository here: https://github.com/Seyrinian/seyri ...

What sets React.FC<T> apart from Function() in TypeScript?

Do arrow functions and function notations differ from each other? It seems like these two methods function in the same way. One is written as React.FC<T> while the other as Function(). Is this simply a matter of notation, or are there deeper reaso ...

Creating dynamic components from JSON elements does not trigger a rerender of components within an array

Imagine having a simplified input structure like this: [ { type: "text", text: "how are you {name}" }, { type: "input", input: "name" }, { type: "text", text: "good to ...

The chart is failing to refresh with the latest response information (using Chart.js version 3.2.1 and ng2-charts version 3.0.0-beta.9)

I recently upgraded my project using Chart.js version 3.2.1 and ng2-charts version 3.0.0-beta.9. Initially, everything seemed to be working fine with mock data - the charts were displaying as expected. However, when I switched to testing with real backend ...