Jasmine beforeEach not called - javascript

Just starting with Jasmine and following the instructions on the Jasmine website for async testing I notice the beforeEach function is never called.
Any idea why not? I don't find any hints relevant anywhere on the web. Thanks.
Code
The code is really simple:
describe("Testing test.php", function()
{
it ("Gets me a coke", function()
{
var asyncResult = null;
// query function with callback
var queryFcn = function(callback)
{
console.log("queryFcn");
$.get("be_com/test.php?coke")
.success(function(data)
{
asyncResult = data.response;
callback(); // notify jasmine
})
.error(function() { callback(); });
};
// Call ajax
beforeEach(function(done) {
console.log('beforeEach');
queryFcn(done); });
// Evaluate response
expect(asyncResult).toBe("a can of coke");
});
});
The HTML is equally simple:
<html>
<head>
<link rel="shortcut icon" type="image/png" href="../fe_com/js/lib/jasmine-standalone-2.3.4/lib/jasmine-2.3.4/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="../fe_com/js/lib/jasmine-standalone-2.3.4/lib/jasmine-2.3.4/jasmine.css">
<script type="text/javascript" src="../fe_com/js/lib/jquery-2.0.0.min.js"></script>
<script type="text/javascript" src="../fe_com/js/lib/jasmine-standalone-2.3.4/lib/jasmine-2.3.4/jasmine.js"></script>
<script type="text/javascript" src="../fe_com/js/lib/jasmine-standalone-2.3.4/lib/jasmine-2.3.4/jasmine-html.js"></script>
<script type="text/javascript" src="../fe_com/js/lib/jasmine-standalone-2.3.4/lib/jasmine-2.3.4/boot.js"></script>
<!-- FILES -->
<script type="text/javascript" src="testSpec.js"></script>
</head>
<body>
<h2>Unit Tests</h2>
</body>
</html>

A beforeEach block should not be inside of an it block.
The idea of a beforeEach is that the code inside it runs before each of the following it blocks. Example:
beforeEach(function () {
// code in here will run 3 times
});
it('does first thing', function () {});
it('does a second thing', function () {});
it('does a third thing', function () {});

Related

Document 'load' event callbacks not called; how did I mess this up?

In this HTML document, in Chrome, none of my load event callbacks are called:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script>
console.log('just checking');
function someFunction () { console.log('test 3'); }
document.addEventListener('load', () => console.log('test 1'));
document.addEventListener('load', function () { console.log('test 2'); });
document.addEventListener('load', someFunction);
</script>
</head>
<body>
</body>
</html>
However, I can see that they are set in the inspector:
And there are no errors in the console.
I am almost certain this is some trivial error on my part, and I can't figure out what it is.
I spent a fair amount of time searching the internet for reasons, but for the most part every post I found about failed load callbacks generally had to do with accessing the DOM before it was ready, which doesn't really apply here.
I hand-wavily tried setting the defer attribute on the script but it had no effect.
What am I missing here... ?
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script>
function docReady(func) {
document.addEventListener("DOMContentLoaded", function (event) {
func(event);
});
}
function someFunction () { console.log('test 3'); }
docReady(() => console.log('test 1'));
docReady(function () { console.log('test
2'); });
docReady(someFunction);
</script>
</head>
<body>
</body>
</html>
use 'DOMContentLoaded' instead 'load'

Make sure two functions in different files run in the correct order?

So I have two functions in different files.
File 1 looks like this:
function 1() {
do something
}
window.addEventListener('load', () => {
1();
});
and file two looks like:
function 2() {
do something
}
window.addEventListener('load', () => {
2();
});
I want function 1 to run before function 2.
Currently I do this by importing them like this;
<head>
<script src="file1">
<script src="file2">
</head>
The problem with this is it is quite fragile as if someone where to switch the imports then it would stop working, so I am asking if there is a better way of doing it to ensure that function 1 will be run before function 2(and no I can't put them in the same file).
Remove the event listeners from the JS files and wire up the events in the html file.
<head>
<script src="file1">
<script src="file2">
window.addEventListener("DOMContentLoaded", () => {
1()
2()
});
</head>
Better yet, load up the scripts at the end of the <body> which will help with faster load times of the raw html.
<head>
<!-- not much here -->
</head>
<body>
<!-- html -->
<script src="file1">
<script src="file2">
<script>
window.addEventListener("DOMContentLoaded", () => {
1()
2()
});
</script>
</body>

How to write unit tests for events in backbone.js

I begin my adventure with write unit tests so please be indulgence. In my app I am using jQuery, backbone.js and underscore.js and for tests mocha.js and chai.js. I have problem because I have no idea how to test events using this tools. Fox example I have function which changes value of input. It call after change checkbox value.
test.html file:
<!DOCTYPE html>
<html>
<head>
<title>Backbone.js Tests</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" href="js/lib/mocha.css" />
<script src="js/lib/mocha.js"></script>
<script src="js/lib/chai.js"></script>
<!-- <script src="js/lib/sinon.js"></script> -->
<script>
// Setup
var expect = chai.expect;
mocha.setup('bdd');
// Run tests on window load event.
window.onload = function () {
(window.mochaPhantomJS || mocha).run();
};
</script>
<!-- App code -->
<script src="../public/static/js/libs/jquery-2.1.4.min.js"></script>
<script src="../public/static/js/libs/js.cookie-2.1.0.min.js"></script>
<script src="../public/static/js/libs/bootstrap.min.js"></script>
<script src="../public/static/js/libs/underscore-min.js"></script>
<script src="../public/static/js/libs/backbone-min.js"></script>
<script src="../public/static/js/libs/backbone-relational.min.js"></script>
<script src="../public/static/js/libs/backbone-super.min.js"></script>
<script src="../public/static/js/libs/handlebars-v4.0.5.min.js"></script>
<script src="../public/static/js/application.js"></script>
<script src="../public/static/js/main.js"></script>
<script src="../public/static/js/views/register.js"></script>
<script src="../public/static/js/views/modals/sign-in-modal.js"></script>
<script src="../public/static/js/views/modals/sign-up-modal.js"></script>
<script src="../public/static/js/helpers/forms.js"></script>
<script src="../public/static/js/helpers/alerts.js"></script>
<script src="../public/static/js/helpers/inpage-alerts.js"></script>
<script src="../public/static/js/collections.js"></script>
<script src="../public/static/js/models.js"></script>
<script src="../public/static/js/kodilla.lib.js"></script>
<script src="../public/static/js/views/knowledge-base.js"></script>
<script src="../public/static/js/libs/tether.min.js"></script>
<!-- Tests -->
<script src="js/spec/register.spec.js"></script>
</head>
<body>
<div id="mocha"></div>
</body>
</html>
register.js file:
App.Views.Register = Backbone.View.extend({
events: {
'click input[name="terms"]' : 'changeTermsConfirmation',
'click [type=submit]': 'onSubmitForm'
},
initialize: function(options) {
this.$termsConfirmedAtHidden = this.$('input[name="terms_confirmed_at"]');
},
changeTermsConfirmation: function(e) {
if ($(e.currentTarget).is(":checked")) {
this.$termsConfirmedAtHidden.val(Math.floor(Date.now() / 1000));
} else {
this.$termsConfirmedAtHidden.val('');
}
},
onSubmitForm: function() {
if (!this.$el.find('input[name="terms"]').is(':checked')) {
analytics.track('auth_register_not_checked_terms');
}
}
});
register.spec.js file:
$(document).ready(function() {
describe('Register Form', function() {
App.registerView = new App.Views.Register();
describe('initialize() function', function() {
it('Should initialize this.$termsConfirmedAtHidden variable by HTML object', function () {
expect(App.registerView.$termsConfirmedAtHidden).to.be.a('object');
});
});
describe('changeTermsConfirmation() function', function() {
it('Should set value of $termsConfirmedAtHidden element', function () {
//how to test this function
});
});
});
});
My question is how to write sensible unit test for "changeTermsConfirmation()" function. I'll be thankful for others notes, usage tips.
Maybe I can help you out with a few bits of info which might get you started.
Mocha/Chai is modular, so first you need to include a mocking/spying library into your project. The default choice for most people seems to be Sinon (along with Sinon-Chai).
Then you can examine and unit test your event handler:
Create a view instance for your test.
Set up a spy on the view method you want to test (changeTermsConfirmation in your case)
Trigger the event by calling trigger on your view instance
Your expectation can check how often your method has been called, and with which arguments, and what its return value has been.
If you don't care about any of that and just want to test view state changes, you don't need a spy (and you don't need to include a library like Sinon). Just create a view instance, call trigger and examine the result.

How can I test the part of code that executes before onready?

I have written a small page to learn BDD/TDD. It is at http://duolingo.howyousay.it/link.html
My tests (only one file at the moment) are at http://duolingo.howyousay.it/tests/test.html?coverage&hidepassed&noglobals
I've managed to get 100% code coverage except for 5 lines in http://duolingo.howyousay.it/duolingo_link_fixer.js
1 var DuolingoLinkFixer = function() {
2 this.data = {};
3 var self = this;
4
5 document.onreadystatechange = function () {
* 6 self.init();
7 }
8 };
9
10 DuolingoLinkFixer.prototype.init = function() {
* 11 if (document.readyState == "complete") {
* 12 this.setOriginalUrl();
* 13 this.setAlternateText();
* 14 this.setFixedUrl();
15 }
16 }
Lines 6 and 11-14 don't get tested, but if I remove them, the code doesn't work. I'm using QUnit, QUnit-BDD and Blanket.js. How can I test the part of code that runs before onready as it seems that the tests only start running after onready?
My test code currently starts like this:
describe("DuolingoLinkFixer", function() {
describe("new", function() {
it("should create a new instance of DuolingoLinkFixer", function() {
expect(new DuolingoLinkFixer instanceof DuolingoLinkFixer).to.be.true();
});
});
});
This is the source for my test HTML page:
<!DOCTYPE html>
<html>
<head>
<title>Duolingo JavaScript tests</title>
<script type="text/javascript" src="/lib/jquery/jquery-3.0.0.js"></script>
<script type="text/javascript">
$.holdReady(true);
</script>
<link type="text/css" rel="stylesheet" href="/lib/qunit/qunit-1.23.1.css">
<script type="text/javascript" src="/lib/qunit/qunit-1.23.1.js"></script>
<script type="text/javascript" src="/lib/qunit-bdd/qunit-bdd.js"></script>
<script type="text/javascript" src="/lib/blanket.js/blanket.min.js"></script>
<script type="text/javascript" data-cover src="../url_helper.js"></script>
<script type="text/javascript" data-cover src="../duolingo_link_fixer.js"></script>
<script type="text/javascript" src="test_url_helper.js"></script>
<script type="text/javascript" src="test_duolingo_link_fixer.js"></script>
</head>
<body>
<div id="qunit"></div>
</body>
</html>
I tried adding jQuery's $.holdReady(true); as suggested in another post but it didn't help. I don't need to use jQuery so I'm trying to avoid it for this project.
It turned out that I only needed to add a single line to my test code to test the previously untestable code:
describe("DuolingoLinkFixer", function() {
describe("new", function() {
it("should create a new instance of DuolingoLinkFixer", function() {
expect(new DuolingoLinkFixer instanceof DuolingoLinkFixer).to.be.true();
document.onreadystatechange();
});
});
});
Adding document.onreadystatechange(); runs the code exactly the same as if it had been triggered by the readyStateChange event.

Give selector.method as parameter, call it

I've got a function $.doSomething() which does some stuff and then should call other functions in the jQuery-form of $('selector').function(). I do not want $.doSomething() to know about what it's calling, that should be decided by the user.
I created a small example on JSBin:
http://jsbin.com/umonub/11/edit
Is it possible to store the call to $('#foo').doStuff(); in a function-object and give it as parameter to a function which then calls it?
Here's the sample-code (in case somebody can't access JSBin or it gets deleted there):
script.js
$(document).ready( function() {
var callback = $('#foo').doStuff();
$.doSomething(callback);
});
$.extend({
doSomething: function(callback) {
//do some stuff
//call the callback
}
});
$.fn.doStuff = function() {
$(this).text("Stuff Done");
};
index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<p id="foo"></p>
</body>
</html>
Sure, just put $('#foo').doStuff() inside a function:
var callback = function() {
$('#foo').doStuff();
};

Categories

Resources