2016-06-02 4 views
1

У вас есть разочаровывающая проблема в Карма и Angular2, которые я попытался свести к простейшей демонстрации: рассмотрите этот класс TypeScript как с подходом члена экземпляра, так и с элементом статического члена к тому же действию:Невозможно Jasmine SpyOn Статический член TypeScript

export class Echo { 

    static classLog = console.log; 

    instanceLog = console.log; 

    static classEcho(msg: string) { 
     this.classLog(msg); 
    } 

    instanceEcho (msg: string) { 
     this.instanceLog(msg); 
    } 
} 

... то простой чистый тест машинопись, как это:

import {Echo} from './echo'; 

var e = new Echo(); 
e.instanceEcho('instanceEcho!'); 
Echo.classEcho('classEcho!'); 

..results в:

instanceEcho! 
classEcho! 

Хорошо.

Однако, попытайтесь проверить то же самое от Жасмин:

import {it} from '@angular/core/testing'; 
import {Echo} from './echo'; 

describe('Logging',()=> { 
    it('instanceEcho will invoke \'console.log()\'',() => { 
     spyOn(console, 'log'); 
     expect(console.log).not.toHaveBeenCalled(); 
     var e = new Echo(); 
     e.instanceEcho('test instanceEcho'); 
     expect(console.log).toHaveBeenCalledWith('test instanceEcho'); 
    }); 

    it('classEcho will invoke \'console.log()\'',() => { 
     spyOn(console, 'log'); 
     expect(console.log).not.toHaveBeenCalled(); 
     Echo.classEcho('test classEcho'); 
     expect(console.log).toHaveBeenCalledWith('test classEcho'); 
    }); 
}); 

..results в:

START: 
✔ instanceEcho will invoke 'console.log()' 
LOG: 'test classEcho' 
✖ classEcho will invoke 'console.log()' 

SUMMARY: 
✔ 1 tests completed 
✖ 1 test failed 

FAILED TESTS: 
    ✖ classEcho will invoke 'console.log()' 
     Chrome 50.0.2661 (Mac OS X 10.11.5) 
    Expected spy log to have been called with [ 'test classEcho' ] 
    but it was never called. 

Поскольку статический метод делает фактически работают должным образом, почему Жасмин не захватывая его ?

+0

интересно ... но оба метода '' classEcho' и instanceEcho' не имеют один и тот же код. Что произойдет, если вы удалите весь контент и вызовите только 'console.loge (msg)'? Так ли это работает? – iberbeu

+0

Я протестировал его, и это сработало для меня. Я полагаю, что ваша проблема действительно находится внутри метода 'this.classLog (msg);' – iberbeu

+0

Вы правы, что 'instanceEcho' и' classEcho' оба обеспечивают шаг косвенности, и я мог бы удалить эту косвенность и вызвать 'console.log 'непосредственно .. но точка косвенности заключается в том, чтобы позже разрешить другой регистратор быть назначенным во время выполнения. –

ответ

0

Я понимаю, что это не проблема Jasmine, шпионящая за статическими членами TypeScript, а просто старая проблема JavaScript с потерей ссылки на this. Жасмин SpyOn будет правильно ловить инвокации console.log(), если я переключаюсь, например .:

export class Echo2 { 

    static classLogger = console; 
    instanceLogger = console; 

    static classEcho(msg: string) { 
     this.classLogger.log(msg); 
    } 

    instanceEcho (msg: string) { 
     this.instanceLogger.log(msg); 
    } 
}