Reputation: 126
I could save the original method in a variable in beforeEach, and then restore it in afterEach, but maybe I can use a spy which will be reset automatically between test suites.
spyOn(Ext, "create").andCallFake(function(className){
if (className === 'Waf.view.Viewport')
// call the original Ext.create method
});
Is this possible? I am using Jasmine 1.3
Upvotes: 7
Views: 6605
Reputation: 1781
Here is how I achieved it using Jasmine with an Angular Service. The service I am spying on is being called in the constructor of my test service:
// create the TestBed:
TestBed.configureTestingModule({
providers: [MyInjectedService, ServiceConstructorInjectedService]
});
myInjectedService = TestBed.get(MyInjectedService);
serviceConstructorInjectedService = TestBed.get(ServiceConstructorInjectedService);
it('should...', () => {
let returnValue = 'return this';
spyOn(serviceConstructorInjectedService , 'myFunction').and.callFake((param) => {
if (param === 'testValue') {
return returnValue;
} else {
return ServiceConstructorInjectedService.prototype.myFunction(param);
}
});
});
// instantiate the service again so spy is called
myInjectedService = new MyInjectedService(
TestBed.get(ServiceConstructorInjectedService)
);
Upvotes: 0
Reputation: 1418
This is a hack for Jasmine 2.3. Ideally the fake callback should have access to the reference of the original function to call as needed instead of dancing around like this.
Given that stubbing strategy can be modified on the fly in Jasmine 2.3, the following approach seems to work as well:
var createSpy = spyOn(Ext, "create");
createSpy.and.callFake(function(className){
if (className === 'Waf.view.Viewport'){
createSpy.and.callThrough();
Ext.create(className);
}
});
Upvotes: 6
Reputation: 1456
You can bind the original method into the fake:
var obj = {
method: function(name) { return name + '!'; }
}
var methodFake = function(original, name) {
return 'faked ' + original(name);
}.bind(obj, obj.method)
spyOn(obj, 'method').andCallFake(methodFake);
obj.method('hello') // outputs 'faked hello!'
For what it's worth, I don't think it's great practice to do this, but the need came up for me recently when I was testing some d3 code. Hope it helps.
Upvotes: 8
Reputation: 6940
Different scenarios should be tested independently of each other. Try structuring your tests to something like this.
beforeEach(function () {
spyOn(Ext, 'create');
});
describe('scenario 1', function () {
beforeEach(function () {
Ext.create.andCallThrough();
});
it('should do something', function () {
// do your assertions
});
});
describe('scenario 2', function () {
beforeEach(function () {
Ext.create.andCallFake(function () {
// faked function
});
// or if you're always returning a constant value, use andReturn
// Ext.create.andReturn({});
});
it('should do something', function () {
// do your assertions
});
});
Upvotes: -1
Reputation: 126
I ended up doing something like this:
var origFunc = Ext.create;
spyOn(Ext, "create").andCallFake(function(className, classConfig){
if (className === 'Waf.view.Viewport') {
return {};
} else {
return origFunc.apply(null, arguments);
}
});
Upvotes: -1