Jest mockResolvedValueOnce/mockReturnValueOnce access function parameter - jestjs

I want to write a mock function that will return different values at each call. The problem I have is that the returned value is depends on the parameter value passed to the function.
//something like this
window.fetch = jest.fn(urlPath)
.mockResolvedValueOnce(fetch({urlPath}))
.mockResolvedValueOnce(fetch({urlPath, arg1: 1}));

I found this, maybe help jest-when, not sure it works
import { when } from 'jest-when';
window.fetch = jest.fn(urlPath);
when(window.fetch).calledWith({urlPath, arg1: 1}).mockReturnValue('test');
await expect(window.fetch({urlPath, arg1: 1})).resolves.toEqual('test')

Use a mock implementation. It allows you to pass a function and handle it in a granular way.
jest.mockImplementation((arg1, arg2) => return whatever(arg1, arg2))

Related

Mock alert with fn() from another function

I have a file1.js with a function that fires up alert():
file1.js
export function test(value){
alert(value); //string
}
file1.test.js:
import { test } from "./test";
...
it("returns value", () => {
window.alert = jest.fn();
test(10);
expect(window.alert).toHaveBeenCalledWith("10");
});
Could someone point me out how to get the alert called?
What you're doing is mocking a function, which you can view how to do in this link here.
When you mock a function, you're essentially obtaining the instance(s) of the said functions. You may also find that using the jest.spyOn() function will also help too and more or less does the same thing.
Another thing to note is that you're testing what the function does, which is how I undergo writing my unit tests. This pattern is known as AAA (Arrange, Act, Assert) which you should read up on in this link.
-Ehsan
In Codesandbox instead of alert() it should be window.alert()

How to export async function?

following is my code -
abc.js
class abc {
async foo1() {
// do something
return result;
}
async foo2() {
// do something
return result;
}
module.exports = abc
}
another-file.js
const abc = requir(./abc);
abc.foo1();
// this results in error
// TypeError : abc.foo1 is not a function
How should I do this?
Several points. By convention class names starts with capital letter. Your problem has nothing to do with async functions. You have 2 options to solve this problem. First option is to make your function static. Then you can use it directly without instance. Second option is just call it differently: instantiate class first to get instance, and then call your method on this instance.
And also keep in mind, that await keyword can be used only inside other async function. And you need await keyword if you want to handle promise, returned by async function (it returns promise of result, not result)

Require.js: is it possible for `define` to use node-style `next()` to delay returning a value?

see codes below:
define(["dep1"], function (dep1, next) {
// necessary works here so that `dep2` is ready
// kind of circular dependency.
someNecessaryWork();
require(["dep2"], function (dep2) {
// return value in node-style, using `next()`
next(someValue);
}
// do not return value as normal, no `return someValue` here
}
Is require.js able to do this? For now I'm using functions to achieve this.
define(["dep1", "dep2Fn"], function (dep1, dep2Fn) {
someNecessaryWork();
dep2Fn();
return someValue;
});
but it feels not intuitive.
define does not allow you to set the return value of a module through a callback. What you show in your second snippet is how you do it. You just have to get used to it.

Node tutorial - LearnYouNode - Juggling Async - using nested callbacks

I was trying to solve the "Juggling Async" problem in the "learnyounode" workshop from nodeschool.io. I saw a lot of questions here about this problem where it is not working because the url's were being called from a loop. I understand why that wouldn't work.
I had tried something like this.
var http=require('http');
console.log(process.argv[2],process.argv[3],process.argv[4]);
fn(process.argv[2],
fn(process.argv[3],
fn(process.argv[4])));
function fn(url,callback){
http.get(url,function(response){
var string='';
response.setEncoding('utf8');
response.on('data',function(data){
string+=data;
});
response.on('end',function(){
console.log(url,string);
if (callback) {
callback();
}
});
});
};
As per my understanding, the second GET call should go out only after the first one has ended, since it is being initiated after response end. But the output is always in different order.
I have seen the correct solution. I know that doing it this way fails to leverage the advantage of async, but shouldn't the callbacks make it output in order?
When you pass in a function as a callback, you need to only pass in the function name or function definition. By providing the arguments, you are actually calling the function.
E.g. let's say you had a function f1 that took in another function as a parameter, and another function f2 that you want to pass into f1:
function f1(func_param) {
console.log('Executing f1!');
}
function f2(a_param) {
console.log('Executing f2!');
}
When you do the following call (which is similar to what you are doing, providing a callback function and specifying parameters for the callback):
f1(f2(process.argv[2]));
You're evaluating f2 first, so 'Executing f2!' will print first. The return of f2 will get passed as a parameter into f1, which will execute and print 'Executing f1!'
In your call
fn(process.argv[2],
fn(process.argv[3],
fn(process.argv[4])));
You are saying, let's pass the result of fn(process.argv[4]) as a callback to fn(process.argv[3]), and we'll get the result of calling that and pass that as a callback to fn(process.argv[2]).

function in the function's parameter

the function is in function's parameter,for example
function getAcceptLanguages() {
chrome.i18n.getAcceptLanguages(function(languageList) {
var languages = languageList.join(",");
setChildTextNode('languageSpan',
chrome.i18n.getMessage("chrome_accept_languages", languages));
})
}
the function is " chrome.i18n.getAcceptLanguages()"
the function in function's parameter is :function(languageList) {...}
i really dont get it....how to send data to the languageList.
hope someone can answer for me
chrome.i18n.getAcceptLanguages is a async operation, so it need a callback function to return the languageList result. The browser will find the accept languages, then call the callback function with the result languageList as the parameter. So that you can get the result in the callback function.

Resources