I'm using Jasmine to test this
class X{
test(obj){
return obj.someFunction()+100
}
}
so my spec is
it("test if someFunction is called and return value calculated correctly",()=>{
let x = new X()
let mockObj= jasmine.createSpyObj(["someFunction"])
mockObj.someFunction.and.callFake(()=> 2000)
let returnValue= x.test(mockObj)
expect (mockObj.someFunction).toHaveBeenCalled()
expect (returnValue).toBe(2000+100)
})
And this is ok Now I want to check if the parameter of test() is an object as data type so I want to do this
spyOn(x,"test")
let mockObj= jasmine.createSpyObj(["someFunction"])
x.test(mockObj)
expect(x.test.calls.allArgs()[0][0]).toBeInstanceOf(Object)
And this is ok in another it()
But why can't we do both in the same it() block? Is it not valid to use spyOn() and createSpyObj() in the same it() block?
If I did so the it() will fail! and this is the error I'm getting
Expected spy unknown.someFunction to have been called
Expected undefined to be 2100
When we do
spyOn, we are attaching a spy on the method and letting go of its implementation details. So after we spy ontestmethod, we can see how many times it was called, how it was called, etc. but we lose it's implementation details (what's inside of the method).To get the best of both worlds (still have implementation details and know if it was called, how it was called, etc.), we need to use
.and.callThrough();.Change the first line here like so:
That way, the
testmethod will be spied upon and the actual method will be called.Edit You can use
callFakeas well but you have to provide a function implementation.You can do something based on the argument. In this case, if it exists, it will return 300 and if it doesn't, it will return 400;