I want to test in Javascript using Mocha.
Approach that I want to use is ->
- Keep the test cases in Database.
- Before running the tests fetch the test cases from Database.
- Generate tests(it functions) dynamically using the data fetched from Database.
- Execute the tests.
Issue that I'm having is that when and where to make the Database call to fetch the test cases??
This call cannot be in the before hook because it runs before it but not describe. So, test cases need to fetched even before the describe is called.
Please suggest something that will be helpful in implementing the above mentioned approach.
I have searched a lot for implementing this approach and the only valid solution that I have got is using the parameter delay.
delay flag can be passed to mocha and you can make mocha wait till the async calls are resolved(for me database calls).
After async calls are resolved, run() function can be called which will start the execution of the tests.
Related
Is it possible to configure jest to await any pending promises before exiting, to avoid log noise caused by pending code being called after the last test is finished, at which point jest will have torn down the environment?
I have an application which starts by initializing some services asynchronously. If calls are made to these services, the pending background work will first be awaited, and then the task executed. If no calls are made however, the services will invisibly be running init code in the background that no-one cares about.
The problem arises when my tests finish too quickly; if this happens before this pending init work is done, strange things happen - my log gets full of noise which I at first couldn't at all understand - calls like JSON.stringify would fail with cannot access JSON of object null, which turned out to be because jest had torn down the environment so that the global object, containing symbols like JSON was now null (_environment.global.JSON).
I can add an afterAll() hook that simply waits for a second or so, but this seems ugly, and also adds the question what kind of delay is needed; this might break randomly if initialization sometimes takes 100 ms and sometimes 1100 ms.
I could of course add code to afterAll() that makes dummy service calls simply to guarantee that any pending initialization is awaited.
But I would rather like a general, configuration based approach to this, if there is one?
So, is there a way to tell jest to await all pending promises, either before tests start or after?
Or is there a way to tell jest to add a grace period at the end, after all tests, without having to resort to a manual afterAll() call (which must be placed in a file which all tests import, to still have it working properly if only running some tests etc)?
This question actually asks the same question, but the answer with 177 upvotes doesn't do what the question asked for - it simply awaits any promises that are already fulfilled but not handled by the micro tasks queue yet. It does not await any promises that are still pending.
ive found out that its a best practice for nodeJS / ExpressJS as an API-Endpoint for a ReactJS Software to only use asynchornus functions for mysql-querys etc.
But i really dont get how this should work and why it decrease performance if i didnt use it.
Please imagine the following code:
API Endpoint "/user/get/1"
Fetches every datas from user with id one and responds with a json content. If i use async there is no possibility to respond with the information gathered by the query, because its not fulfilled when the function runs to its end.
If i wrap it in a Promise, and wait until its finished its the same like a synchronus function - isnt it?
Please describe for me whats the difference between waiting for a async function or use sync function directly.
Thanks for your help!
If i wrap it in a Promise, and wait until its finished its the same
like a synchronus function - isnt it?
No, it isn't. The difference between synchronous and async functions in JavaScript is precisely that async code is scheduled to run whenever it can instead of immediately, right now. In other words, if you use sync code, your entire Node application will stop everything to grab your data from the database and won't do anything else until it's done. If you use a Promise and async code, instead, while your response won't come until it's done, the rest of the Node app will still continue running while the async code is getting the data, allowing other connections and requests to be made in the meantime.
Using async here isn't about making the one response come faster; it's about allowing other requests to be handled while waiting for that one response.
What is the point of mocking the method of an external library when unit testing?
Let's say that I have a function that uses XYZ library to get the current user using a given authorization token, and then if it finds the user, it returns a valid AWS policy:
export const getUser = async token => {
const user = await XYZ.getUser(token)
return {
// valid policy
context: user,
}
}
If an invalid token is given, the getUser should throw an error.
What is the point of testing this function if the XYZ.getUser is already well tested?
Why mock the getUser instead of using the real one?
You wouldn't want to invoke the actual HTTP request for XYZ.getUser(token), due to the following reasons.
1) The objective of unit testing is to test a specific behaviour, and in your very case, it is to test that your getUser function actually works.
2) You wouldn't want to make an actual request to the backend, as that would usually mean writing/reading/deleting something from the database. In many cases, it is not a good idea to overcomplicate your unit testing, as such operations should not be tested on the front-end, since you would want to limit and simplify your unit testing to test for a very specific behaviour.
3) Since the main objective is to test the above behaviour, you would want to simplify and limit what you are testing. As such, you will need to understand that unit testing of network requests of XYZ.getUser(token) should be done at the server-side, instead of client-side (or front-end).
4) By mocking the response from XYZ.getUser(token), we can simulate multiple scenarios and responses, such as successful responses (Code 200 OK), and other types of errors (business logic errors from the backend, or network errors such as error 400, 500, etc). You can do so by hardcoding the required JSON responses from XYZ.getUser(token) on the different types of scenarios you need to test.
this goes back to the definition and usages of unit tests.
Unit tests are supposed to test well defined functionality, for example you might write an algorithm and the functionality of that is very well defined. Then, because you know how it's supposed to function then you would unit test that.
Unit tests by definition, are not meant to touch any external systems, such as but not limited to files, APIs, databases, anything that requires going outside of the logical unit which is the code you want to test.
There are multiple reasons for that among which is execution speed. Calling an API, or using a third party call, takes a while. That's not necessary a problem when you look at one test, but when you have 500 tests or more then the delays will be important. The main idea is that you are supposed to run your unit tests all the time, very quickly, you get immediate feedback, is anything broken, have I broken something in other parts of the system. In any mature system you will run these tests as part of your CI/CD process and you cannot afford to wait too long for them to finish. no, they need to run in seconds, which is why you have the rules of what they should or should not touch.
You mock external things, to improve execution speed and eliminate third party issues as you really only want to test your own code.
What if you call a third party API and they are down for maintenance? Does that mean you can't test your code because of them?
Now, on the topic of mocking, do not abuse it too much, if you code in a functional way then you can eliminate the need for a lot of mocking. Instead of passing or har-coding dependencies, pass data. This makes it very easy to alter the input data without mocking much. You test the system as a while using integration / e2e tests, this gives you the certainty that your dependencies are resolved correctly.
I have several scenarios to be executed. I introduce some test data in the database (using beforeAll) before executing these scenarios and remove such data after executing the scenarios.
The problem is that if a scenario fails, the code present within afterAll is not being executed. Therefore, test data is not removed from the data base. Is there any other way to accomplish this?
Thanks in advance.
First, You should mock the database connection, there are many libraries to do so, for instance if you are using mongodb have a look at Mockgoose
Mockgoose provides test database by spinning up mongod on the back when mongoose.connect call is made. By default it is using in memory store which does not have persistence.
For the afterAll hook that never runs (Which is the default behavior in case a test fails):
I suggest you truncate everything in the beforeAll hook, so whenever you start running the tests you have an empty database, even if you have some data from the last run (which will not be the case if you use Mockgoose or similar)
I can't think of a case where, in JavaScript, I would need a unit test to wait for a callback completion.
Unit testing is about testing the smallest parts, the units. So I would write tests:
for the function I'm testing
for the callback function
to check the function calls the callback correctly using a mock (or spy)
But I see in testing frameworks such as Jasmine or Mocha that they allow for asynchronous testing. I guess it makes sense in integration tests (or BDD) but not unit tests. Do you have examples of unit tests that would need asynchronous testing?
I agree with you that asynchronous testing is more relevant for behavioral driven development (BDD) tests where you are creating real world use cases rather than going through a list of methods per object and checking they perform as expected.
As for unit testing, I would say there is still a place for asynchronous tests. Say you are testing a class and one of the methods performs an AJAX request to a REST entry point in order to get some data and return a result (for example authenticate a user), this is still a single unit of computation, ie:
Auth.validate({user: "smithj", pass: "mypwd"});
However if you perform your test synchronously you would not be able to check that the method has executed correctly as you would be checking for a result before obtaining a response from the remote entry point.