2016-05-19 5 views
0

У меня есть проблема:Как шпионить за функцией вызова другой функции в Жасмин?

var async = require('async'); 

function a() { 
    async.series([b,c], function(err) { 
    console.log('Done'); 
    }); 
}; 
function b(next) { 
    next(); 
}; 
function c(next) { 
    next(); 
}; 

var methods = { 
    a: a, 
    b: b, 
    c: c 
}; 

И я пытаюсь написать тест следующим образом:

spyOn(methods.a); 
methods.a(); 
expect(methods.b).toHaveBeenCalled(); 
expect(methods.c).toHaveBeenCalled(); 

Однако и б и не регистрируются в качестве того, вызывался. Любые идеи, как правильно проверить это поведение?

ответ

0

Если вы используете функцию-шпион по функции или методу, тогда Jasmine будет рассматривать эту функцию для проверки, позвоните ей. И вызываемая функция под Jasmine Spy не выполняет свой код по умолчанию.

spyOn(methods, "a"); 
methods.a(); 
expect(methods.a).toHaveBeenCalled(); 

В вашем случае необходимо проверить выполнение асинхронного кода. Мы можем сделать это с done функции:

it("should support async execution", function(done) { 
    var MAX_ASYNC_DELAY = 2000; 
    spyOn(methods, "b"); 
    spyOn(methods, "с"); 
    methods.a(); 
    setTimeout(function(){ 
     expect(methods.b).toHaveBeenCalled(); 
     expect(methods.c).toHaveBeenCalled(); 
     done(); 
    }, MAX_ASYNC_DELAY); 
}); 

Это будет работать, если в methods.a() вы будете использовать в следующем:

function a() { 
    async.series([methods.b, methods.c], function(err) { 
      console.log('Done'); 
    }); 
} 

Если такая корректировка не представляется возможным, вы должны переписать тестовый пример в следующем:

it("should support async execution", function(done) { 
    var MAX_ASYNC_DELAY = 2000; 
    spyOn(window, "b"); 
    spyOn(window, "с"); 
    methods.a(); 
    setTimeout(function(){ 
     expect(b).toHaveBeenCalled(); 
     expect(c).toHaveBeenCalled(); 
     done(); 
    }, MAX_ASYNC_DELAY); 
}); 

Owen Ayres советует не использовать setTimeout в тестовом случае. Но это невозможно в вашем случае, если вы используете Жасмин. Потому что jasmine.DEFAULT_TIMEOUT_INTERVAL - это тайм-аут, ожидающий вызова done. Например, ваш асинхронный тайм-аут составляет около 10000 мс, и вы устанавливаете MAX_ASYNC_DELAY в 11000 мс. Тестовый случай будет отмечен как неудачный, потому что jasmine.DEFAULT_TIMEOUT_INTERVAL равен 5000 мс по умолчанию. Это использование необходимо переопределить эти параметры:

var originalTimeout; 
beforeEach(function() { 
    originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; 
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 12000; // ms to wait for done() 
}); 
it("should support async execution", function(done) { 
    var MAX_ASYNC_DELAY = 11000; 
    // test case from above 
}); 
afterEach(function() { 
    jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; 
}); 

, если вы используете жасмин версию 2.2 и выше, вы можете написать:

it("should support async execution", function(done) { 
    var MAX_ASYNC_DELAY = 11000; 
    // test case from above 
}, 12000); 
0

Избегайте setTimeout в модульном тесте любой цене. Вот как вы должны тестировать его в читаемом формате «Triple A Testing». Использование асинхронизации Jasmine done гарантирует, что он ждет определенный промежуток времени перед сбоем, если вызов функции никогда не будет выполнен. Если вы хотите настроить это для этого тестового примера, вы можете сделать что-то вроде определенного в my beforeEach ниже (но внутри самого теста).

beforeEach(function() { 
    // these are not required, including to show you can have if desired 
    originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; 
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; // ms to wait for done() 
}); 

it('calls methods b and c when a is called', function (done) { 
    var a = spyOn(methods.a); 
    var b = spyOn(methods.b); 

    methods.a(); 

    expect(a).toHaveBeenCalled(); 
    expect(b).toHaveBeenCalled(); 
    done(); 
}); 

afterEach(function() { 
    // could be inline of above test if not needed for multiple cases. 
    jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; 
}); 

Не используйте таймаутов в тесте. Это не является чистым способом тестирования, и его следует избегать, если только абсолютно существенный.

+0

«Не использовать тайм-ауты» --- Как еще вы можете задержать вещь? 'waitsFor' ушел :(:(:(http://stackoverflow.com/questions/37310701/how-to-use-jest-to-test-react-rendered-async-data – FizzBuzz

+0

@FizzBuzz Я ответил на ваш вопрос вопрос, но вы можете немного уточнить свой код – Shakespeare

Смежные вопросы