如何使用jasmine.js测试控制台输出?

12

我正在学习Nicholas Zakas的《Web前端开发专业JavaScript》这本书,并使用Jasmine.js测试其中的示例。

目前,我可以通过指定函数的返回值来测试函数的输出,但是当我想要返回多个数据片段时就会遇到麻烦。

教材使用alert()方法,但这很麻烦,我不知道如何测试警报。我想知道是否有一种方法可以测试console.log()的输出。例如:

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

    return(person.name);    //Nicholas
    return(person.age);     //29
});

我知道我可以将它们作为一个字符串返回,但对于更复杂的示例,我想能够测试以下内容:

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

    console.log(person.name);    //Nicholas
    console.log(person.age);     //29
});

Jasmine测试看起来像这样:

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

有没有一种简单的方法可以做到这一点,而我只是错过了呢?我对编程还比较新,所以任何指导将不胜感激。


3
嗯,不对,return(person.name); return(person.age); 是完全错误的。只有 第一个 return 语句会执行,第二个永远不会被执行。这里更大的问题是你似乎在测试函数的内部细节。你真的没有必要知道函数的内部实现,你应该只测试它的输出。你所返回的任何东西都是你应该测试的内容。 - user229044
2个回答

26

你的上面的代码有几个问题。正如所指出的,拥有多个返回语句是无法工作的。而且,定义一个新对象时,最好使用对象字面量语法而不是使用 new Object

通常情况下,你会做类似这样的事情:

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

  return person;
};

使用上面的函数,你可以采用几种方式进行测试。其中一种方法是使用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);
});
另一种方法是测试函数的实际输出。
it("should return a person", function () {
    var person = function_to_test();
    expect(person).toEqual({ name : "Nicholas", age : 29 });
});

1
您不能使用Jasmine Spy覆盖本机控制台函数。它们是不可分配的。 - Erik Donohoo
1
当然,当然。出于某种原因,我本来以为需要输入另一个子变量到 console.log 中,比如 console.log.print 或者其他什么来测试实际打印到控制台的内容。这只是语义问题,对吧?谢谢并点赞,C§。 - CSS
console.log = jasmine.createSpy('log') 对我很有用。我建议将原始函数保存在变量中,以便在测试后恢复。我必须使用 beforeEachafterEach 来实现这一点。 - Jordan Pickwell
@JordanPickwell:你能告诉我你在 afterEach 中使用了什么吗? - Gagan
3
@Gagan:抱歉回复晚了。在我的测试文件顶部,我有一个“let originalLogFunc”。在“beforeEach”中:beforeEach(function () { originalLogFunc = console.log; console.log = jasmine.createSpy('log') })。而“afterEach”则相反:afterEach(function () { console.log = originalLogFunc; originalLogFunc = undefined }) - Jordan Pickwell

5

我知道这是一个老问题(7年以上),但今天我通过Google搜索找到了这个答案。从这个答案中,我做了以下更改并成功地解决了我的问题。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接