What is the best way to simulate global variables that are declared in a separate file?

dataConfiguration.js

var userData = {
    URIs: {
        APIURI: "C" 
    },
    EncryptedToken: "D"
};

configSetup.js

config.set({
    basePath: '',
    files:['dataConfiguration.js' ],
    .....

UserComponentDetails:

.....some imports
import { UserDetailsService } from '../user-details.service';
declare var userData: any;
@Component({
    .....more code

    userFilter() {     
        return userData.URIs.APIURI;
    }
}

Testing:

describe('UserComponentDetails', () => {
    let subject:any;
    let fixture: ComponentFixture<UserComponentDetails>; 

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ UserComponentDetails ],
            providers: [{ provide: UserDetailsService, useClass: 
            UserDetailsServiceStub }],
        });
        fixture = TestBed.createComponent(UserComponentDetails);
        subject = fixture.componentInstance;          
    });

    it('should return Z', () => {
        subject.userData = {
            URIs: {
                APIURI: "Z"
            },
            EncryptedToken: "W"
        };
        let result = subject.userFilter();
        expect(result).toBe("Z");
    });   
});

Result:

ReferenceError: userData is not defined

To resolve this issue, a method has been implemented inside the component to retrieve the userData global variable.

getUserData():any{
    return userData;
}

Additionally, mocking this method in the test suite:

let n = {
    URIs: {
        APIURI: "mockedValueAPIURI",
    },
    EncryptedToken: "mockedEncryptedToken",
};
let spy = spyOn(subject, 'getUserData').and.returnValue(n);

Is there a way to mock global variables like this without needing to wrap them in methods and then mock the method instead of the variable? The goal is to keep the original application code intact if written by someone else.

Answer №1

When working with files, it's important to note that you cannot access variables from other files or mock imports. Dependency injection (DI) becomes your best ally in these situations, allowing you to provide a mock class for testing purposes.

In order to test services that retrieve data, you'll need to create mocks instead of relying on separate files. One approach is to export JSON or objects and utilize the exported data.

TestBed.configureTestingModule({
    imports: [
    ],
    declarations: [
        ComponentDetailsComponent,
    ],
    providers: [
        {
            provide: RealService,
            useExisting: StubService,
        },
    ],
}).compileComponents();

To implement the stub, follow this example:

class StubService implements Partial<RealService> {
    getuserInfo() {
        return { ...mockedData };
    }
}

Additionally, when dealing with mocking HTTP calls, make sure to use HttpTestingController.

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

How to access a file stored within a proxy object using Vue.js

I am currently working on sending a file from a vue-page to the server. To achieve this, I have implemented the following: FileFrom component: <template> <div class="FileForm" v-bind:name="name"> <label clas ...

Establish characteristics for the temporary print document

Struggling to configure the properties of a temporary file created for later printing by the user. Here's a breakdown of the process: User clicks on "Print Map Area" button on the website. A menu appears asking for preferred dimensions (e.g. A4 ...

Clear SELECT After Submission

I have a jQuery script and need a function to reset the SELECT input after it has been submitted. <script> $(document).ready(function() { //elements var progressbox = $("#progressbox"); var progressbar = $("#progressbar"); var statustxt = ...

Implementing a Reset Button to Clear Checkboxes with PHP or JavaScript

I'm looking for help with setting up a button to reset the checkboxes on my preferences page. UPDATEL: Here's more information: The solutions provided should only affect checkboxes that are currently selected, not those enabled onLoad. This is ...

The construction was unsuccessful due to errors in the webpack process

I encountered a sudden error in my Next.js app. Is there any solution available to resolve this issue? ./pages/_app.tsx Error: [BABEL] C:\Projects\skribeNew\app-web\pages\_app.tsx: You provided us with a visitor for the node type T ...

Exploring how to utilize optional URL parameters within Express.js

When using Express.js version 4.14, I implemented the following route: app.get('/show/:name/:surname?/:address?/:id/:phone?', function(req, res) { res.json({ name: req.params.name, surname: req.params.surname, address ...

Using jQuery to trigger an action when a user clicks on a regular audio element

Is there a way to detect a click on the default audio element of a browser using jQuery? I'm having trouble getting it to work in Chrome. $('audio').click(function(){ alert("You have clicked on an audio player"); }); <script ...

Encountered an issue with Angular and Ionic 4 when attempting to listen to real-time data: InvalidPipeArgument error was thrown for the AsyncPipe with an empty argument

In my ionic 4 app, I am attempting to implement real-time message updates using angularfire2 and the Firebase Realtime Database. The code snippet is shown below: When running this code, it throws an error: Error: InvalidPipeArgument: '' for pip ...

Using ejs-locals in Express.js to insert script tag with data

Using ejs-locals for express 3.x (https://github.com/RandomEtc/ejs-locals) How can I add a script tag with dynamic data in a template? In my layout.ejs file, I currently have: <%- block.scripts %> In my page template login.ejs, I want to replace ...

The program experienced an issue with TypeError: Attempting to access properties of an undefined variable ('_id')

I am attempting to show a data entry (with a unique id) in Angular, but I'm encountering the following error: ERROR TypeError: Cannot read properties of undefined (reading '_id') The service for retrieving the specific id is defined as: g ...

Assigning the style of the parent element based on the child element

Currently, I am attempting to develop a customized dropdown field and here is the code I have come up with: const list = document.querySelector('.list'); const listItems = list.getElementsByTagName('p'); document.querySelector('# ...

Concealing a division element if there is no content inside of it

As a newcomer to jQuery, I am experimenting with setting up a code that hides a div when the 'innerHTML' is null. However, my attempt using the code below is not working. Can anyone point out where I might be going wrong? if (($("#php-errors").h ...

Mastering the Art of Promises in RXJS Observables

After thoroughly researching SO, I stumbled upon numerous questions and answers similar to mine. However, I suspect that there might be gaps in my fundamental understanding of how to effectively work with this technology stack. Currently, I am deeply enga ...

Jenkins process encounters issues with sed execution

I am currently facing an issue where a script that runs successfully locally encounters difficulties during our Jenkins build process, specifically with the 'sed' command. Below is the code snippet I am using. I have double-checked the file path ...

Decorate the elements that do not contain a specific child class

I'm currently working on an angular project with primeng for the UI components. My focus at the moment is on customizing the p-menu component, specifically the appearance of list items that are not active. The challenge I'm facing is that the act ...

Loading dynamic content within Angular Material tabs allows for a more customized and interactive user experience

I am currently working on creating a dynamic tab system using Angular Material: Tabs. I have encountered an issue with loading content on tabs after the initial one, where the functionality only works when the first tab is loaded. Below you can see the ta ...

Prevent ASP.NET Core routing from intercepting Angular 5 routing calls during deep linking operations

I am currently utilizing ASP.NET Core MVC for managing API calls, with routing set to api/*. Additionally, Angular 5.x is being used alongside its own routing system. Everything functions smoothly when running locally (Core on port 5000 and Angular on 420 ...

Discover the following `<td>` identifier through the act of clicking on a separate `<td>` element

I have a few td's with specific ids: <td id="first">first</td> <td id="second">second</td> <td id="third">third</td> <td id="fourth">fourth</td> Whenever I click on one of the td elements, I want to re ...

What is the reason that the protected keyword is not retained for abstract properties in TypeScript?

I'm uncertain whether this issue in TypeScript is a bug or intended functionality. In my Angular project, I have 3 classes - an abstract service, a service that implements the abstract service, and a component that utilizes the implementing service. ...

What is the method to turn off readonly property for input fields in Laravel?

I'm encountering an issue with my Laravel project. I have a form with an input field that has the readonly attribute set. <input type="text" name="anamFam" id="anamFam" value="{{$aFam->anam_cont}}" readonly> When I click the edit button, I ...