13

I'm working through the text: Professional JavaScript for Web Developers by Nicholas Zakas and I'm testing the examples with Jasmine.js.

I can currently test the output of a function by specifying a return a value, but I'm running into trouble when there are multiple pieces of data that I want to return.

The textbook uses the alert() method, but this is cumbersome and I don't know how to test for alerts. I was wondering if there was a way to test for console.log() output. For instance:

function_to_test = function(){ var person = new Object(); person.name = "Nicholas"; person.age = 29; return(person.name); //Nicholas return(person.age); //29 }); 

I know I can have them return as one string, but for more complicated examples I'd like to be able to test the following:

function_to_test = function(){ var person = new Object(); person.name = "Nicholas"; person.age = 29; console.log(person.name); //Nicholas console.log(person.age); //29 }); 

The Jasmine test looks something like:

it("should test for the function_to_test's console output", function(){ expect(function_to_test()).toEqual("console_output_Im_testing_for"); }); 

Is there a simple way to do this that I'm just missing? I'm pretty new to coding so any guidance would be appreciated.

1
  • 3
    Errr, no, return(person.name); return(person.age); is completely wrong. Only the first return statement will execute, the second will never be reached. The larger problem here is that you seem to be testing the internals of a function. You really have no business knowing what the function does internally, you should only be testing its output. Whatever you're actually returning from that function is what you should test. Commented Nov 6, 2013 at 23:27

3 Answers 3

27

There are a couple of things that are wrong with your code above. As pointed out, having multiple return statement will not work. Also, when defining a new object, it is preferable to use the object literal syntax over using new Object.

What you would normally do is something more like this:

var function_to_test = function () { var person = { name : "Nicholas", age : 29 }; return person; }; 

Using the function above, there are a couple of ways you could test this. One it to mock out the console.log object using Jasmine Spies.

it("should test for the function_to_test's console output", function () { console.log = jasmine.createSpy("log"); var person = function_to_test(); expect(console.log).toHaveBeenCalledWith(person); }); 

The other is to test the actual output of the function.

it("should return a person", function () { var person = function_to_test(); expect(person).toEqual({ name : "Nicholas", age : 29 }); }); 
Sign up to request clarification or add additional context in comments.

5 Comments

You cannot override the native console functions using a jasmine spy. They are unassignable
Of course, of course. For some reason I was expecting to have to enter another sub-variable to the console.log like console.log.print or something to test what was actually printed to the console. Semantics, right? Thanks and +1, C§
console.log = jasmine.createSpy('log') worked for me. I recommend saving the original function in a variable so it can be restored after the tests. I had to use beforeEach and afterEach to do this.
@JordanPickwell : can you please let me know what did you use in your afterEach ??
@Gagan: Sorry for the late reply. I have let originalLogFunc near the top of my test file. beforeEach: beforeEach(function () { originalLogFunc = console.log; console.log = jasmine.createSpy('log') }). afterEach is the reverse: afterEach(function () { console.log = originalLogFunc; originalLogFunc = undefined }).
6

I know this is an old question (7+ years old) but I just came upon this answer today through Google search. From this answer, I changed it to the following and has worked for me.

spyOn(console, 'error'); const dto = new DTO(); // add to console.error if no parameter is given expect(console.error).toHaveBeenCalled(); 

Comments

0

Please try this,

function_to_test = function(){ var person = new Object() person.name = "Nicholas" person.age = 29 console.log(person.name) //Nicholas console.log(person.age) //29 }); describe('test',()=>{ it("should test for the function_to_test's console output", ()=>{ const logSpy = spyOn(console, 'log') function_to_test () expect(logSpy.calls.count()).toBe(2) // "console.log" called twice expect(logSpy.calls.all()[0].args[0]).toBe("Nicholas") expect(logSpy.calls.all()[1].args[0]).toBe(29) }) }) 

Hope it helps,

thanks

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.