What is difference between method `toHaveBeenCalled()` and `andCalledThrough()` - angularjs

While using the Jasmine Spies, how different is andCalledThrough() method from toHaveBeenCalled, does it actually run the original method completely? Any ideal scenarios when I should use it?

These are two different steps in spying on a function.
When you declare a spy on a function, before the function is called, you can attach some instructions to what should be done when the function is called. and.callThrough() means that the actual implementation will be used. Other options are and.callFake() and and.returnValue(), which allow you to mock a response and not use the actual implementation.
After the function you spied on was called, you can verify it was called using expect and toHaveBeenCalled and its variations.
Please refer to the documentation.

Related

Redux hooks in regular function (rules-of-hooks)

I'm having a trouble with a regular function. In my component, I'm loading lot of products with a function that is reusable everywhere. So I have a file named products.js where some functions are defined.
In a function called 'getPrice', I need to get a param called 'beautifullPrice' stored in the redux store, on a reducer.
If I do it respecting hooks rules, I have to implement useSelector in my components and pass 'beautifullPrice' as a param in every functions. But my 'getPrice' is a sub sub sub call. So I need to declare 'beautifullPrice' in tons of functions, and this param cant change till the application is not reloaded.
So, in my opinion, the easiest way to do this is to use useSelector directly in my function 'getPrice', all my functions wont have one more params, it will be cleaner. But according to react-rules, I should not do this.
First question : Why this rule ? I tried and it seems to work well.
Second question : Is there an other proper way to do this ?
Am I the only one facing this type of problem ? =D
Thx for reading, and for help !

How to mock a specific object returned as a response to function call?

I have an implementation where I want to mock a service that I have created:
this.device = major.get('alp").devC === 'devType';
This is happening in the constructor of a component. I want to mock the same in my jest test case and what I have done is:
jest.spyOn(major, 'get').mockImplementation(() => {
return { devC: 'devType2' };
});
I checked and can see that my code is going inside my mock and is returning the values correctly, but when I run the test cases I get devC of undefined.
I checked by putting logs in the component but then test failed at test case stating the same error above but prints correctly on the console screen where test were running with watch.
I think I found the solution to the problem. So the issue is with the place where you put the jest.spyOn. Since I was having the method call inside the constructor, It was important to put the spy even before we create the wrapper instance or even before we take the reference of the component in shallow/mount.
If you are having any such requirement to spy on the method in the constructor call you best bet could be to put spy first thing in your test case or in beforeEach() (if you want it to be applicable on all test cases).

What is the difference between jest.fn() and jest.spyOn() methods in jest?

I am writing the Unit test cases for my react project and using jest and enzyme for writing test cases. I have read the jest documentation
https://jestjs.io/docs/en/jest-object.html#jestspyonobject-methodname
which explains about jest.spyOn() method but I didn't understand completely.
So I want to know more details about the specific places where we should use jest.fn() and Where we should/must use jest.spyOn(). It would be a great help if can be explained with an example for both methods.
Thanks
My simple understanding of these two functions in react/frontend projects is the following:
jest.fn()
You want to mock a function and really don't care about the original implementation of that function (it will be overridden by jest.fn())
Often you just mock the return value
This is very helpful if you want to remove dependencies to the backend (e.g. when calling backend API) or third party libraries in your tests
It is also extremly helpful if you want to make real unit tests. You don't care about if certain function that gets called by the unit you test is working properly, because thats not part of it's responsibility.
jest.spyOn()
The original implementation of the function is relevant for your test, but:
You want to add your own implementation just for a specific scenario and then reset it again via mockRestore() (if you just use a jest.spyOn() without mocking it further it will still call the original function by default)
You just want to see if the function was called
...
I think this is especially helpful for integration tests, but not only for them!
(Good blog post: https://medium.com/#rickhanlonii/understanding-jest-mocks-f0046c68e53c)
To my understanding the only difference is that YOU CAN RESTORE ORIGINAL FUNCTION with jest.spyOn and you can't with jest.fn.
Imagine we have some hook that calls a function when component is rendered, here we can just check the function was called, we do not test that function.
Another case if we want original function to test how it works. And we need both in one test file.
Real method:
myMethod() {
return 33;
}
With jest.fn()
const myMethod = jest.fn().mockImplementation(() => 25);
const result = myMethod();
expect(result).toBe(25);
In case we want to test now real myMethod, we can't restore it back to normal with jest.fn().
Another thing with spies:
const spy_myMethod = jest.spyOn(component, "myMethod").mockImplementation(() => 25);
const result = myMethod();
expect(result).toBe(25);
And now if we want the original myMethod
spy_myMethod.mockRestore();
const result = myMethod();
expect(result).toBe(33);
jest.fn() is a method to create a stub, it allowing you to track calls, define return values etc...
jest.spyOn() came from jasmine, it allow you to convert an existing method on an object into a spy, that also allows you to track calls and re-define the original method implementation.
My rule of thumb on this is: if you want to make an existing implementation a spy use spyOn if you are building a mock, use fn().

Can I call an event handler with a parameter using inline declaration of the parameter without having the function be recreated on every render?

As I have understood it the following way to call an event handler is
+ compact and simple to read
-, but causes a new myWrapperFunc function to be created on every render
However, creating functions is cheap right? That that minus is insignificant, right?
Am I correct in my understanding that this way to pass an event handler with a parameter will not cause a new handler instance to be created on each render?
handler(event, val) {
...
}
<Component onClick={myWrapperFunc = (e) => handler(e, "myVal")}>
First of all, you are passing the function wrong. It should be:
<Component onClick={(e) => handler(e, "myVal")}>
If we talk about the main question, I'm not an expert but there is still not an agreement on this subject. There is a reality that your callback function is created in every render and this causes a performance loss. But how significant is this loss? This depends on your app probably.
Is it a big app which includes so many components that create callbacks like that. So, you should consider an optimization then. Some people say if you don't need optimization then don't bother with it :) Some says follow the best practices.
You can pass parameters to your functions without using them like that but somehow you should get these parameters in your component. If it is a prop then use it directly instead of passing it like that for example. Then use a separate function and its reference. You don't need to pass e for a callback, it is passed by automatically with callbacks.
handler () => {
use(event);
use(props.val);
use(val_variable_in_component;
...
}
..
<Component onClick={handler}>

how does aurajs sandbox.on() and sandbox.emit() works?

I am new to auraJS and have gone through documentation but did not understand what is the role of sandbox in application. According to docs sandbox.on() is subscriber(listener) and sandbox.emit is publisher. but what are the argument passed in these functions and how i can call a function of other component with sendbox.emit(). i have code in the application like
sandbox.emit('layout:add-requested', this.collection, layoutModel);
and through debugging i come to know above line of code calls renderAddLayout() of other component's view. but i could not find any relationship or asynchronous call which can trigger the renderAddLayout() function();

Resources