Jasmine에서 프로그래밍 방식으로 스파이를 어떻게 제거합니까?
프로그래밍 방식으로 재스민 테스트 스위트의 스파이를 어떻게 제거합니까? 감사.
beforeEach(function() {
spyOn($, "ajax").andCallFake(function(params){
})
})
it("should do something", function() {
//I want to override the spy on ajax here and do it a little differently
})
좋은 아이디어인지 확실하지 않지만 단순히 isSpy
함수 의 플래그를 false로 설정할 수 있습니다 .
describe('test', function() {
var a = {b: function() {
}};
beforeEach(function() {
spyOn(a, 'b').andCallFake(function(params) {
return 'spy1';
})
})
it('should return spy1', function() {
expect(a.b()).toEqual('spy1');
})
it('should return spy2', function() {
a.b.isSpy = false;
spyOn(a, 'b').andCallFake(function(params) {
return 'spy2';
})
expect(a.b()).toEqual('spy2');
})
})
그러나 스파이의 다른 행동이 필요한 경우에 새로운 제품군을 만드는 것이 더 나은 아이디어 일 수 있습니다.
로 설정 isSpy
하는 false
것은 매우 나쁜 생각입니다. 스파이를 감시하고 Jasmine이 사양이 끝날 때 스파이를 제거하면 원래 방법을 얻지 못하기 때문입니다. 방법은 첫 번째 스파이와 동일합니다.
이미 메서드를 감시하고 있고 원래 메서드를 대신 호출 andCallThrough()
하려면 첫 번째 스파이 동작을 재정의하는 호출해야합니다 .
예를 들면
var spyObj = spyOn(obj,'methodName').andReturn(true);
spyObj.andCallThrough();
당신은 전화로 모든 스파이를 지울 수 있습니다 this.removeAllSpies()
( this
- 사양)
나는 그것이 .reset () 이 무엇인지 생각합니다 .
spyOn($, 'ajax');
$.post('http://someUrl', someData);
expect($.ajax).toHaveBeenCalled();
$.ajax.calls.reset()
expect($.ajax).not.toHaveBeenCalled();
따라서 스파이는 사양간에 자동으로 재설정됩니다.
andCallFake()
a 내에서 사용한 beforeEach()
다음 사양 내에서 강제로 변경하려고 시도 하면 원래 함수의 "복원"의 이점을 실제로 얻지 못합니다 (이것이 그렇게하지 못하게하는 이유 일 수 있습니다).
따라서 특히 스파이가 jQuery와 같은 전역 개체에 설정되는 경우주의하십시오.
데모:
var a = {b:function() { return 'default'; } }; // global scope (i.e. jQuery)
var originalValue = a.b;
describe("SpyOn test", function(){
it('should return spy1', function(){
spyOn(a, 'b').andCallFake(function(params) {
return 'spy1';
})
expect(a.b()).toEqual('spy1');
});
it('should return default because removeAllSpies() happens in teardown', function(){
expect(a.b()).toEqual('default');
});
it('will change internal state by "forcing" a spy to be set twice, overwriting the originalValue', function(){
expect(a.b()).toEqual('default');
spyOn(a, 'b').andCallFake(function(params) {
return 'spy2';
})
expect(a.b()).toEqual('spy2');
// This forces the overwrite of the internal state
a.b.isSpy = false;
spyOn(a, 'b').andCallFake(function(params) {
return 'spy3';
})
expect(a.b()).toEqual('spy3');
});
it('should return default but will not', function(){
expect(a.b()).toEqual('default'); // FAIL
// What's happening internally?
expect(this.spies_.length).toBe(1);
expect(this.spies_[0].originalValue).toBe(originalValue); // FAIL
});
});
describe("SpyOn with beforeEach test", function(){
beforeEach(function(){
spyOn(a, 'b').andCallFake(function(params) {
return 'spy1';
})
})
it('should return spy1', function(){
// inspect the internal tracking of spies:
expect(this.spies_.length).toBe(1);
expect(this.spies_[0].originalValue).toBe(originalValue);
expect(a.b()).toEqual('spy1');
});
it('should return spy2 when forced', function(){
// inspect the internal tracking of spies:
expect(this.spies_.length).toBe(1);
expect(this.spies_[0].originalValue).toBe(originalValue);
// THIS EFFECTIVELY changes the "originalState" from what it was before the beforeEach to what it is now.
a.b.isSpy = false;
spyOn(a, 'b').andCallFake(function(params) {
return 'spy2';
})
expect(a.b()).toEqual('spy2');
});
it('should again return spy1 - but we have overwritten the original state, and can never return to it', function(){
// inspect the internal tracking of spies:
expect(this.spies_.length).toBe(1);
expect(this.spies_[0].originalValue).toBe(originalValue); // FAILS!
expect(a.b()).toEqual('spy1');
});
});
// If you were hoping jasmine would cleanup your mess even after the spec is completed...
console.log(a.b == originalValue) // FALSE as you've already altered the global object!
Jasmine 2에서 스파이 상태는 SpyStrategy 인스턴스에 보관됩니다. 이 인스턴스를 호출 할 수 있습니다 $.ajax.and
. GitHub에서 Jasmine 소스 코드를 참조하십시오 .
따라서 다른 가짜 방법을 설정하려면 다음을 수행하십시오.
$.ajax.and.callFake(function() { ... });
원래 방법으로 재설정하려면 다음을 수행하십시오.
$.ajax.and.callThrough();
이것은 Jasmine 2.5에서 나를 위해 일하여 mock ajax의 재설정을 허용했습니다.
function spyOnAjax(mockResult) {
// must set to true to allow multiple calls to spyOn:
jasmine.getEnv().allowRespy(true);
spyOn($, 'ajax').and.callFake(function () {
var deferred = $.Deferred();
deferred.resolve(mockResult);
return deferred.promise();
});
}
Then you can call it multiple times without error. spyOnAjax(mock1); spyOnAjax(mock2);
Or you can do it
describe('test', function() {
var a, c;
c = 'spy1';
a = {
b: function(){}
};
beforeEach(function() {
spyOn(a, 'b').and.callFake(function () {
return c;
});
})
it('should return spy1', function() {
expect(a.b()).toEqual('spy1');
})
it('should return spy2', function() {
c = 'spy2';
expect(a.b()).toEqual('spy2');
})
})
In this case you use the same Spy but just change the var that it will return..
I'm posting this answer to address the comment in OP @Tri-Vuong's code - which was my main reason for my visiting this page:
I want to override the spy ... here and do it a little differently
None of the answers so far address this point, so I'll post what I've learned and summarize the other answers as well.
@Alissa called it correctly when she explained why it is a bad idea to set isSpy
to false
- effectively spying on a spy resulting in the auto-teardown behavior of Jasmine no longer functioning as intended. Her solution (placed within the OP context and updated for Jasmine 2+) was as follows:
beforeEach(() => {
var spyObj = spyOn(obj,'methodName').and.callFake(function(params){
}) // @Alissa's solution part a - store the spy in a variable
})
it("should do the declared spy behavior", () => {
// Act and assert as desired
})
it("should do what it used to do", () => {
spyObj.and.callThrough(); // @Alissa's solution part b - restore spy behavior to original function behavior
// Act and assert as desired
})
it("should do something a little differently", () => {
spyObj.and.returnValue('NewValue'); // added solution to change spy behavior
// Act and assert as desired
})
The last it
test demonstrates how one could change the behavior of an existing spy to something else besides original behavior: "and
-declare" the new behavior on the spyObj previously stored in the variable in the beforeEach()
. The first test illustrates my use case for doing this - I wanted a spy to behave a certain way for most of the tests, but then change it for a few tests later.
For earlier versions of Jasmine, change the appropriate calls to .andCallFake(
, .andCallThrough()
, and .andReturnValue(
respectively.
From jasmine 2.5, you can use this global setting to update a spy within your test cases:
jasmine.getEnv().allowRespy(true);
just set the spy method to null
mockedService.spiedMethod = null;
참고URL : https://stackoverflow.com/questions/8885591/how-do-we-clear-spy-programmatically-in-jasmine
'programing' 카테고리의 다른 글
position : relative는 빈 공간을 남깁니다. (0) | 2020.10.28 |
---|---|
이전 git 병합 후 git rebase (0) | 2020.10.28 |
Elastic Beanstalk의 Linux AMI에서 Tomcat 7 설치 폴더는 어디에서 찾을 수 있습니까? (0) | 2020.10.28 |
sizeof (unsigned double)가 4와 같은 이유는 무엇입니까? (0) | 2020.10.28 |
Scala의 액터는 Go의 코 루틴과 비슷합니까? (0) | 2020.10.28 |