First:
If you are not able to set window.event to a dummy value in your test,
you could try rewriting your code to take it in as a parameter:
function taskNodeSelected(event) {
// ...
}
Then the test code would be:
jack(function() {
var dummyNode = { id: "myDummyNode" };
var dummyEvent = { srcElement: dummyNode; }
jack.expect("changeCurrentElement")
.withArguments(dummyNode)
.once();
jack.expect("JS_getEditorURL")
.withArguments(dummyNode.id)
.once();
taskNodeSelected(dummyEvent) ;
});
Second:
If you get an error saying JS_getEditorURL is undefined, you need to
create a dummy for that to. You can do that manually:
window. JS_getEditorURL = function() { }
Do that on the first line of your test or in test setup code. The rest
of the Jack code remains the same.
Third:
You can find an example of how to use Jack with QUnit here:
http://github.com/keronsen/jack/tree/master/docs/examples/qunit
Karl-Erik
The example works for me. Are you sure you have an updated version of
jack.js? The qunit integration was added very recently.
And yes, you can use mocking in your jQuery example:
(Assuming you still use qunit)
// Test 1
jack(function() {
jack.expect("$").withArguments("#idTreeView").returnValue({length:0});
equals(doesTreeViewExist(), false);
}
// Test 2
jack(function() {
jack.expect("$").withArguments("#idTreeView").returnValue({length:1});
equals(doesTreeViewExist(), true);
}
Karl-Erik
Sorry for the late answer.
> 1) Is it possible to test $(document).ready(function() {...}); ?
You could use a named function (for example startApplication) instead,
and run your tests against that. You would then change your code to
call that function: $(document).ready(startApplication);
It is probably also possible to mock ready(), but I don't think thats
the best option. This could work:
jack(function(){
var mockJQueryDocument = jack.create("mockJQueryDocument", ["ready"]);
jack.expect("$")
.whereArgument(0).is(document)
.returnValue(mockJQueryDocument);
// ... insert expectations for what should happen when document is ready.
mockJQueryDocument.ready();
});
> 2) I am looking at testing the following code using Jack:
[...]
You should avoid mocking the inner workings of jQuery. Instead you can
include jQuery to support things like $.ready when you write and run
tests, and only use mocking when you want to do interaction testing.
That way, your code coud call $.each(array) without you having to mock
$.each. You can still test what happens inside the each loop with
mocking.
> b) $(this).remove();
>
> As for that one I'm a bit lost, as I'm not sure how Jack will be
> mocking the removing function. My guess is that I'll have to re-mock
> the array with the specific item removed?
Sometimes it is better to set up a DOM structure that you can run your
tests against, and then check it for side-effects, like an element
that should not exist any more. You could use jQuery for setting up
the DOM and checking for elements in your tests.
> 3) Another thing I found strange is that say for the below code and
> test code:
> function doSomething()
> {
> var ID = "id";
> if($('#' + ID).length == 0)
> {
> return false;
> }
> else
> {
> return true;
> }
> }
>
> // test code
> jack.expect("$").withArguments("#id").exactly("5").returnValue
> ( {length:0} );
> doSomething();
>
> I was expecting the test to fail since I have only called doSomething
> () once, but it passed instead. This doesnt make sense, because I
> used the same trick in the test file you provided, and the test failed
> as expected. Am I missing something/understood the wrong thing in my
> test code?
I don't know why it does not work. If you have a similar example that
works, there is probably something that is different between them. Did
you forget the jack(function() { ... }) wrapper?
Karl-Erik
[... deleted previous discussion ...]
There are a few typing errors in your examples that may cause you
trouble, but it would not make the test pass unexpectedly. (Its
returnValue(), not returnVAlue(). Also, there is a = where you
probably should have a ==)
I have tried to recreate the problem with JsTestDriver, but the tests
failed as expected.
If you want me to look further into this problem I suggest you isolate
it in a set of files and send it to me (kero...@gmail.com) so that I
can run exactly what you are running.
Karl-Erik
There are two ways I can think of:
The first is outlined in an earlier reply: Create a normal, named
function that is the event handler for the document.ready event. You
can then call that function in your tests. You won't be testing the
event, but rather the application startup.
The other way is to create a html document that includes the js file
that has document.ready in it. Open an iframe with that document
during your test, and do assertions against the state of the document
to check that the event handler has been called. You should probably
only do a simple "smoke test".
I guess those two kinds of tests together would cover your needs.
Karl-Erik