A guide on effectively testing the value of Object.constructor using Jasmine and minimizing redundancy in the it statements for AngularJS

In my AngularJS application, I have defined an object model like this:

.factory('Watermark', function () {

    // Constructor, with a class name
    // Assumption: the backend provides us with a topic or not!
    function Watermark(content, title, author, topic) {
        this.content = content;
        this.title = title;
        this.author = author;
        if(topic) {
            this.topic = topic;
        }
    }

    // Example Public method, assigned to prototype
    Watermark.prototype.getDocumentType = function () {
        return this.content;
    };

    return Watermark;
});

Now, I want to test this using Jasmine. I want to verify that when I create a new instance of an object, its constructor has the value of the function I used (in this case, Watermark). My current test is failing, as shown below...

describe('Service: Watermark', function () {

    // Load the module / app
    beforeEach(module('MyAppName'));

    var Watermark;

    beforeEach(inject(function (_Watermark_){
        Watermark = _Watermark_;

        setTimeout(function(done) {
            done();
        }, 1);

    }));

    it('should be defined', function () {
        expect(Watermark).toBeTruthy();
    });

    describe('when defining a watermark with content "Book"', function () {

        it('should be an instance of "Watermark"', function () {
            var waterMark = new Watermark('Book','When boyfriends aint so super','Mary Jane','Doomed Romance');

            expect(waterMark instanceof Watermark).toBeTruthy();
        });

        //THIS FAILS!!!
        xit('should have a constructor property "Watermark"', function () {
            var waterMark = new Watermark('Book','When boyfriends aint so super','Mary Jane','Doomed Romance');
            console.log(waterMark.constructor);
            expect(waterMark.constructor).contains('Watermark');
        });

        it('should contain a content property with value "book"', function () {
            var waterMark = new Watermark('Book','When boyfriends aint so super','Mary Jane','Doomed Romance');

            expect(waterMark).toEqual(jasmine.objectContaining({
                content: 'Book'
            }));
        });

        it('should contain a title property with value "When boyfriends aint so super"', function () {
            var waterMark = new Watermark('Book','When boyfriends aint so super','Mary Jane','Doomed Romance');

            expect(waterMark).toEqual(jasmine.objectContaining({
                title: 'When boyfriends aint so super'
            }));
        });

        it('should contain an author property with "Mary Jane"', function () {
            var waterMark = new Watermark('Book','When boyfriends aint so super','Mary Jane','Doomed Romance');

            expect(waterMark).toEqual(jasmine.objectContaining({
                author: 'Mary Jane'
            }));
        });

        it('should contain a topic property with "Doomed Romance"', function () {
            var waterMark = new Watermark('Book','When boyfriends aint so super','Mary Jane','Doomed Romance');

            expect(waterMark).toEqual(jasmine.objectContaining({
                topic: 'Doomed Romance'
            }));
        });
    });

    describe('when defining a watermark with content "journal"', function () {

        it('should not contain a topic property', function () {
            var waterMark = new Watermark('Journal','My pretty lousey life as SpiderMan', 'Peter Parker');

            expect(Object.keys(waterMark)).not.toContain('topic');
        });
    });
});

I am getting an error TypeError: undefined is not a constructor and I'm unsure of what I'm doing wrong here?

Is there a way to reduce the repetition of declaring the new instance within the it('....

Thanks in advance.

Answer №1

It's recommended to utilize the toContains() matcher function instead of contains(). The occurrence of the undefined is not a constructor error might indicate that the test browser is unable to locate the definition for the contains() function, leading to confusion in this scenario.

As for the second part of your inquiry, you can enhance efficiency by declaring var waterMark once within the describe block prior to all tests, and then assigning it within a beforeEach() function.

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

Can anyone suggest a node.js equivalent for XMLHttpRequest.readyState in http?

One important feature of Javascript's XMLHttpRequest object is the readyState property. This property, often used alongside response codes, allows developers to determine if an HTTP request has completed before proceeding with additional code. if (th ...

Issues with the play() method in Javascript across Firefox, Safari, and IE 11 are causing functionality problems

I developed a basic video and audio player that smoothly fades out an introductory image and starts or stops playing an mp4 file upon click. Everything functions properly in Chrome, but unfortunately does not work in other major browsers. Despite checking ...

AngularJS input range is written inside the bubble that crosses over the screen

Is there a way to write inside the bubble of the range slider? I have adjusted the design of the range slider and now I simply want to display the number inside the bubble: Please see image for reference I aim to display the number inside a circle. What ...

The issue of AngularJS dropdown selection not functioning properly in conjunction with ASP.NET MVC has been encountered

Hey there! I'm pretty new to angularjs with asp.net mvc and I've come across an issue with a drop down selection. Whenever I try to select an option from the dropdown, it's not working properly. Here's the HTML code: <select class ...

AngularJS: the use of templateUrl from an external domain is restricted

I have a unique challenge with an app I am developing that will be embedded in other websites. The JavaScript resources for the app are hosted on my server and can be easily embedded into other sites. However, I encountered an issue with a directive that ...

JQuery Slider's Hidden Feature: Functioning Perfectly Despite Being Invisible

Having an issue with a jQuery slider on my local HTML page. The sliders are not showing up as intended. I want it to display like this example: http://jsfiddle.net/RwfFH/143/ HTML <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery ...

Jquery submenu accordion toggles open and closed with each click

My website has a hamburger menu with an accordion-style submenu implemented using jQuery for devices 1084px and smaller. For larger devices, the menu utilizes a hover-style submenu on desktop. However, I encountered issues when trying to use both the hove ...

ExpressJS exhibits unique behavior based on whether the API is requested with or without the specified PORT number

I have encountered an issue with my 2 flutter web apps. One of them is functioning flawlessly when I request the URL, but the other one only works when I include the port xxxxx:4000/nexus-vote. However, when I remove the port, I receive a status code of 20 ...

Node.js Express refuses to serve .js files with absolute URLs

I have encountered a perplexing issue with two files located in /public/widget, namely help.html and help.js http://localhost:8084/widget/help.html When entered into the address bar, it functions normally However, when attempting to access http://local ...

Frustration ensues when working with the Angular + CoffeeScript combination in

Check out this JavaScript JSFiddle that is functional: http://jsfiddle.net/franklovecchio/E3YEt/ Unfortunately, the CoffeeScript JSFiddle provided seems to be broken: http://jsfiddle.net/franklovecchio/E3YEt/230/ Even after adding angular.bootstrap(docum ...

Show a Pair of Images Upon Submission Utilizing Ajax

Imagine having two separate div containers displayed as shown below: https://i.sstatic.net/qQwjV.png What I achieved was clicking the submit button would upload the image to the designated area. However, my goal is for a single click on the button to loa ...

Activate the CSS on a click event using the onClick method

I am trying to implement a transition that triggers when clicking on a specific div element. Currently, the transition only occurs with the active css class. How can I achieve this effect by simply clicking on the div itself? I am using reactjs and believe ...

What could be causing the result to return an empty object?

I am working with Angular JS code that includes a filter: .filter('filterSelectOptionAllowed', function () { var allowed = {1: [0, 1, 2, 3, 4], 2: [0, 1, 2, 3, 4], 3: [1, 2, 3, 4]}; var d = {}; return functi ...

Unusual body padding found in the mobile design

When visiting on a mobile device and inspecting the elements in Google Chrome, try disabling the style rule overflow-x: hidden from the body element and then resizing the window. You may notice a white vertical stripe (padding) appearing on the right side ...

Implementing dynamic checkbox values depending on a selection from a dropdown menu in Angular

In my checkbox list, I have various Samsung mobile models and two offers available. $scope.offers = [ { id: "as23456", Store: "samsung", Offer_message:"1500rs off", modalname: "Samsung Galaxy You ...

Chokidar operates smoothly from the command line, but fails to function properly when invoked through the use of 'npm run'

I've implemented a script that monitors Tailwind CSS files using Chokidar. The script works perfectly when I execute the command in the CLI using chokidar 'tailwind.config.js' --initial=true -c 'npm run build-tailwind'. It successf ...

Implementing Vuejs Array Push in Separate Components

I am attempting to extract data from an object and store it in an array using Vue. My goal is to have each value stored in a separate array every time I click on an item. Each click should push the todo into a different array. How can I achieve this separa ...

Firebase monitors the authentication status of a user

Trying to maintain a global state in my application based on whether the user is logged in or not has me puzzled. Should I only have a single onAuthStateChanged() in my JavaScript file to monitor state changes and manipulate HTML elements like account deta ...

Exploring node.js: How to extract elements from a path

I have an array of individuals as shown below: individuals = ['personA', 'personB', 'personC']; I am looking to create a dynamic way to showcase each individual's page based on the URL. For instance, localhost:3000/indi ...

Employing Ajax.Updater to retrieve a javascript file (prototype.js)

My ajax request is set up as follows: new Ajax.Updater({ success: 'footer' }, '/dyn/actions/checkSystemMessage', { insertion: 'after', evalScripts: true }); The content found at /dyn/actions/checkSystemMessag ...