Experimenting with ngModel in a Jasmine test suite

I've created a directive that generates input fields and connects them to the scope using ngModel. When a user uses this directive in the HTML file like so:

<div tk-quick-form="formStructure" form-data="formData" id="main_form" ></div>

and adds the following in the controller:

$scope.formStructure = [
    {
        fieldName: 'name',
        type: 'string'
    }
];

Then an input field is created with ngModel linking to formData.name.

The directive functions correctly, but I'm unsure how to test it using Jasmine.

Here's what I have tried so far:

Within the it function:

$rootScope.formStructure = [
    {
        fieldName: 'name',
        type: 'string'
    }
];

var element = $compile('<div tk-quick-form="formStructure" form-data="formData" id="main_form" ></div>"')($rootScope);

$(element).find("input#name").val("set")
dump($(element).find("input#name").val()) // outputs "set"

expect($rootScope.formData.name).toBe("set"); //outputs Expected undefined to have value 'set' 
//(though in manual testing $scope.formData.name is actually set because the input field contains ng-model="formData.name")

$rootScope.$digest();

How should I go about writing this test case?

Answer №1

From my perspective, your approach was mostly correct, but with a few exceptions. It would have been ideal to include $rootScope.$digest() before the expect statement. Additionally, triggering 'input' with .triggerHandler('input') is necessary to update the model.

describe('tkQuickForm', function () {
    beforeEach(module('tkQuickForm'));

    beforeEach(inject(function ($rootScope, $compile) {
        this.$rootScope = $rootScope;
        this.scope = $rootScope.$new();
        this.$compile = $compile;
    }));

    it('should pass a basic test', function () {
        expect(true).toBe(true);
    });

    it('should connect ng-model to formData', function() {
        this.scope.formStructure = [
            {
                fieldName: 'name',
                type: 'string'
            }
        ];

        var element = this.$compile(`
            <div tk-quick-form="formStructure" form-data="formData" id="main_form"></div>"
        `)(this.scope);

        this.scope.$digest(); // remember to call digest first

        var input = element.find("input")[0];
        angular.element(input).val('set').triggerHandler('input');

        expect(this.scope.formData.name).toBe("set");
    });
});

Tested with "angular": "~1.5.0". All specifications passed successfully.

https://i.sstatic.net/2ydHC.png

Check out the related pull-request

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

Creating customized Angular-ui Bootstrap tabs using on-the-fly uib-tabset and uib-tab components

As part of my project, I created a tabs panel using angular-ui bootstrap directives. To implement this, I added two html templates - tab.html and tabset.html in a folder named "templates". The code for these templates can also be found on GitHub: tab.html ...

How to handle a Vue element click event through programming

In my Vue instance, I am looking to have a response triggered by a click on an uploaded thumbnail. Utilizing the Vue package called FineUploader Vue with the template layout as outlined in the documentation (refer to end of question). After uploading an i ...

Tips for mocking the router.navigate function in Jest

As a newcomer to unit testing with Jest in Angular, I find myself facing a challenge when it comes to testing components that utilize the this.router.navigate() method. Previously, I used Jasmine for testing and followed these steps: import { Router } from ...

When attempting to run JavaScript within PHP, an Uncaught SyntaxError is encountered

When I run this code without PHP, it works perfectly. <?php $activeStatus = "$getuser[active]"; if($activeStatus == 1) { echo '<script type="text/javascript">'; echo ' $(document).ready(function () { v ...

What is the best way to locate the position of a different element within ReactJS?

Within my parent element, I have two child elements. The second child has the capability to be dragged into the first child. Upon successful drag and drop into the first child, a callback function will be triggered. What is the best way for me to determi ...

"Steps to retrieve the button's ID when using the onClick event in Reactjs

Currently, I am working with Reactjs and Nextjs. I am utilizing functional components instead of classes. Within a loop, I have buttons and I am attempting to retrieve the id of the button when clicked using "onClick". Unfortunately, I am encountering th ...

At what point are routed components initialized?

Here is a route setup I am working with: path: ':id', component: ViewBookPageComponent }, After adding this route, an error keeps popping up: Error: Cannot read property 'id' of null I haven't included a null check in the compo ...

AngularJS - Embedding input fields within an HTML table within a form

The system is up and running now... I retrieve an array and insert the name into an input field. Then, I update the name in the input field and send it back using a PUT request. Here is the HTML code: <form id="edit"> <table> < ...

Utilizing JavaScript AJAX to upload a dynamically generated PDF file to a specific directory on the server

Looking for a solution to save a complex table generated via JavaScript as a PDF on the server. Existing pdf generation libraries have limitations with style and fonts, making it difficult for 'complex' tables. The table can currently be download ...

Exploring the inner workings of self-referencing mechanics in functions

In a recent coding scenario, I encountered this situation: I attempted to define the func1() function and add several static methods to it simultaneously by passing it through the _init() function along with a hash containing properties to attach. However, ...

What is the best way to change the inner text of an HTML element without causing it to resize or impacting its overflow?

Is it possible to change the text content of an HTML element without affecting its size? I am using Bootstrap and the card component. I want to dynamically update the card text without impacting the overflow that I have already set. Here is a sample of t ...

Retrieve data quickly and navigate directly to specified div element on page

I am facing an issue with scrolling on my website. While it currently works fine, I would like to make the scrolling instant without any animation. I want the page to refresh and remain in the same position as before, without automatically scrolling to a s ...

Issues with AngularJS ng-bind-html failing to display list items

I am working with a basic HTML document that looks like this... <ol> <li><strong>Test 1</strong></li> <li><strong>Test 2</strong></li> </ol> ...and I am attempting to connect it to a div ...

Updating a MongoDB subarray with $set now includes adding a new entry rather than just updating existing ones

When trying to update an object in a sub-array, instead of replacing and updating the data, it adds a new entry. Here is the code from controller.js: const updateSubCategory = asyncHandler(async (req, res) => { const { dataArray } = req.body ...

When using a file uploader to set an image on v-model in Vue JS, it sometimes results in

I am currently using Vue JS 2 to develop an image uploader functionality. The input in question has a change function that triggers a function and sets the selected file to the v-model property. After logging the data, I noticed that only an empty object ...

Is there an alternative to the jQuery :contains selector?

How can I choose an option from a drop-down menu based on its text value? When I execute the following code: var desiredText = "Large"; $("#size option:contains(" + desiredText + ")").attr('selected', 'selected'); it ends up selecting ...

Transferring information using pure JavaScript AJAX and retrieving it through a Node API

On the client side, I have the following code: sendMail(e) { e.preventDefault(); var name = document.getElementById('name').value; var contactReason = document.getElementById('contactReason').value; var email = document ...

Instructions for implementing the iPhone Contacts header scroll effect on an HTML webpage

If you take a look at this jsFiddle I've set up, it should give you a better idea of what I'm trying to accomplish: http://jsfiddle.net/nicekiwi/p7NaQ/2/ Imagine the contact page on an iPhone's iOS, where as you scroll through the alphabet ...

When using Node.js with Nginx, requests are timing out at the Nginx level before the processing is completed in Node.js

I have a setup where I use Nginx and Node.js servers. The process involves uploading a file from a browser to Nginx, which then forwards it to Node.js for processing. However, I've encountered an issue when dealing with large files - the upload crashe ...

saving the hash key in a separate array

Currently, I have a collection of key-value pairs that need to be stored in another array. However, I am facing difficulties with the logic as I am unable to keep track of which keys-values have already been assigned while iterating over the list of object ...