I'm trying to test a JavaScript function nested within a jQuery function using Jasmine in a Rails application as follows:
jQuery (function () {
var javascriptFunction = function () {
...functionality being tested...
}
}
When I run the Jasmine test, I get the following error: "ReferenceError: Can't find variable: javascriptFunction"
If I place the JavaScript function outside of the jQuery function, I no longer receive that error; however, that JavaScript function needs to remain within the jQuery function in order for the rest of the application to work.
Is there a way to specify to Jasmine to look for the JavaScript function within the jQuery function?
Ok so now I understand what you are trying to achieve.
There is no way to test what you have done as it is anonymous as you describe in your comments. The best way here is to add that code as a function somewhere. Could be on the window, or preferably on some other class somewhere. You can then test the outcome of calling your function at any point.
The JQuery ready function you are using is really just a way of starting your application. It says 'ok things are ready lets go'. In testing you are wanting that to happen and be repeatable so you can't rely on JQuery to do this.
//Current working version
function doTheThing(){
if ($("#isac").length && $("#isac")[0].checked) {
$(".nested-form-container").show();
enableGraduatedCheckbox();
} else {
$(".nested-form-container").hide();
}
}
jQuery (function () {
doTheThing();
}
Here is a similar discussion around the testability of what you are trying to do and the same suggestions. https://softwareengineering.stackexchange.com/questions/204389/how-to-test-functions-or-the-code-inside-document-ready-using-jasmine
Related
I have plenty of pages on my website with javascript embeded in them.
alert() which is a javascript function has been used in all my scripts atleast once. I want to use custom alert box which will render same in all the browser.
I can define my own function like
function customAlert()
{
// Code goes here.
}
But have to replace alert() withcustomAlert() in all my web pages which is a time consuming process.
Instead can't we just modify native alert function accordingly and it reflects the same as in all browsers.
I think we can't use this
function alert()
{
// Code goes here.
}
because alert is a reserved javascript word for function name.
If there is a better way for implementing the same with different technique, then feel free to answer.
I hate to use jquery or any other frameworks library so please answer regarding pure javascript.
The alert is a property of the global window object, thus you can override it in the following way:
window.alert = function (message){
//do your code
};
and then use it the way you used it before:
alert('hi');
In an effort to avoid repeating code I found it useful to have helper functions that could be called from within a foo.rendered function (for instance). Why is this possible in 0.9.3 of Meteor, but throws an error in 1.0 ?
Template.foo.helpers({
'fooFn' : function(){
return "something"
}
});
Template.foo.rendered = function(){
var something = Template.foo.fooFn();
}
Should I change the syntax in foo.rendered (am I calling it wrong?) or maybe use a different approach entirely (set up functions outside of the helpers({}) and rendered() and call those? or set this up as a registered helper function?
It looks like it is possible as of Meteor 1.0.3.1 to find and call helper functions, although it is clear it's not supposed to be used like this.
Still it can be done:
Template.foo.__helpers[" fooFn"]()
Please notice the leading space for the function name.
The other way of dealing with this is attaching a function to a global namespace, then calling that from somewhere else in your code, as user3557327 mentioned.
Additionally you can use:
Template.registerHelper('myHelper', function (){return 'Look At Me!'})
to register a global helper, and call it explicitly using:
UI._globalHelpers['myHelper']()
I think this would be a better method: How to use Meteor methods inside of a template helper
Define a function and attach it to the template. Call that function from rendered, as well as your template helper. Like MrMowgli said, you probably aren't "supposed" to call template helpers from within the .js file, only from the ...that could probably break in the future.
For example define a function and attach it to the tamplate:
Template.Play.randomScenario = function () { // HACK HACK HACK }
and then call it from your lifecycle method
Template.Play.created = function () {
Template.Play.randomScenario();
};
scenario: function () {
return Template.Play.randomScenario();;
},
I had the same problem and this is the solution I used. Hope that helps.
I want to know how can we hide a function from the javascript console so that it can't be called from it.
To let you better understand the problem , suppose that I have a javascript function that adds some records on the database using Ajax, and anyone else can use this function from the console to add as many records as he wants on the database. I want the function to be called from the web application and not from the console... I tried to obfuscate the code to hide it but we can still find the function from Google Chrome javascript console.
No matter how much you obfuscate and hide your code, any javascript that can be executed on the client side can be executed in the console and you should always be running permissions/security checks on the server side if you wish to have any real control over the security of such functions.
That being said, you can restructure your code inside an immediately invoked function expression which will not be callable as easily from the console as usual like so:
(function() {
var myUncallableFunction = function() { alert('meow'); }
})();
the function myUncallableFunction will only be able to be called from within the parent function as it is a local variable to that parent function and is therefore inaccessible outside of it.
You will still be able to call this function inside of that parent however like so:
(function() {
var myUncallableFunction = function() { alert('meow'); }
myUncallableFunction();
})();
Wondering if there is an elegant way to listen for a function in JavaScript and/or jQuery.
Rather than listening for a $('#mything').click(function(){ //blah }) I'd like to listen for when a specific function is fired off. I don't want to edit the function as it's within a library that I don't want to hack directly.
I did find this: http://plugins.jquery.com/project/jqConnect which connects functions.
But wondering about a better technique.
The only way to do this is to override the function (ie, hack the library):
(function() {
var oldVersion = someLibrary.someFunction;
someLibrary.someFunction = function() {
// do some stuff
var result = oldVersion.apply(this, arguments);
// do some more stuff
return result;
};
})();
Edit: To run your code after the library function has run, just call the library function first, storing the result in a variable. Then, run your code, and finally return the previously stored result. I've updated my example above to accomodate running code either before or after the library function.
This question already has answers here:
How to invoke $(document).ready(function() {}) in unit testing
(5 answers)
Calling $(document).ready(function() {...}); from another file
(1 answer)
Closed 5 months ago.
I have a question in regards to unit testing jQuery's document.ready function().
Currently I have 2 scenarios in my code:
function myFunction()
{
$(document).ready(function() { ... });
}
And:
$(document).ready(function()
{
// some really long setup code here
});
I tried to write a unit test for the first scenario, but I just couldn't get it to run into the document.ready function. As for the second scenario, I haven't come up with a way to test it yet (I'm having trouble coming up with both a way to test it and the syntax).
So assuming I cannot change the source code, are there any ways to test those functions? (assuming it is a good idea to test them)
Thanks.
You do not need to test $(document).ready as it is part of the framework and is already unit tested. When writing unit tests you need to test two things:
Your interaction with the framework. This includes things like making sure that you call the right functions with the right parameters.
Your own code - that your code does the right thing.
So what you really need to do is to make sure that whatever code that gets called from $(document).ready is correct.
function myInit(){
//...
}
function myFunction()
{
$(document).ready(myInit);
}
All you need to do now is to unit test myInit function.
What you can also do is mock out $.ready function to make sure that you are calling it:
var readyCalled = false;
$.ready = function(func){
readyCalled = (myInit == func);
}
//Your code containing `myInit` will get executed somewhere here
//....
//Then test:
test("Should have called ready", function() {
ok(readyCalled, "ready should have been called with myInit as a parameter.")
});
The function that registers the on ready handler should register another function, not an anonymous codeblock. Then you can test the code that calls $.ready() separate from the code that runs on ready. So you have:
One test to verify the right function is set as the the ready handler
Another test to verify the ready handler does the right stuff
To test scenario 1, you'll need to inject a test double for jQuery. This is difficult as if you redefine $ or jQuery, odds are you'll screw up other code that relies on it for other processing (like the test runner). At the same time your code may still want to call jQuery directly when its using utility methods like array concatenation. Any inversion-of-control pattern should address this though (http://martinfowler.com/articles/injection.html).
Anyhow, here's some code using constructor injection (using JSMock for the mocking library, and QUnit (of jQuery) for the test runner):
// the code
var createComponent = function(_$) {
var that = {};
that.OnStart = function() {
_$.ready(this.OnReady);
};
that.OnReady = function() {
};
return that;
};
// the test
test("OnStart associates the ready handler", function() {
var sut;
var mock$ = mc.createMock($);
mock$.expects().ready(isA.TypeOf(Function)).andStub(function(callback) {
equals(callback, sut.OnReady);
});
sut = createComponent(mock$);
sut.OnStart();
mc.verify();
});
test("OnReady does the right stuff", function() {
//etc
});
I use this general pattern for all event handlers in JS... You might prefer to use prototype type classes. When you pass functions as parameters to jQuery, you need to be aware that the "this" value will not be set by jQuery when those callbacks are called. In the test, this breaks because equals(callback, sut.OnReady) no longer passes. To address this, you need to make the event handlers direct members of each instance. You can imagine when there are a number of then its nice to have a util that takes a list of them, but this demonstrates making 'OnReady' a member who does not rely on 'this'.
var Component = function(_$) {
this._$ = _$;
// repeat for each event handler thats tested
this.OnReady = function() {
Component.prototype.OnReady.apply(this);
}
}
Component.prototype.Start = function() {
this._$.ready(this.OnReady);
}
Component.prototype.OnReady = function() {
}