Hi I´m trying to make a unit test creating some fake data and executing a request (using supertest) to check if the controller works well.
The problem rise up when the controller tries to get the fake data, because it exists only inside the transaction.
So my questions are:
Did someone make a junit like test using node.js and express?
How do you manage the database data? How do you do rollback on it?
Thanks in advance.
If I'm understanding you correctly, you are trying to run a bunch of api calls with some fake data, but you are unable to actually get the data from database?
If that's the case, one of two things I would suggest:
Allow your api to update the db, then retrieve from db. When your tests are done, you can do the full clean up at that point (that can be achieve via the after() in mocha)
Use sinon.js, and stub all db calls to return some fake data that you know.
Related
I am attempting to write an Azure CosmosDB integration (Core SQL Api) that integrates with an external service to provide some of the query data. As an example, I need a query made on Cosmos DB to convert some of the data returned (e.g. ID's) by the query into real data by calling an external service via a REST API. This should only happen when querying certain columns.
I initially investigated using a JS stored procedure and/or a UDF to make this external call, but the JS environment seems to be extremely limited and doesn't provide any way to make external calls. I then tried using this https://github.com/Oblarg/cosmosdb-storedprocs-ts repository, which uses webpack to bundle all of node.js into the stored procedure, allowing node modules to be used in stored procedures. Whilst this does allow some node modules to be used, whenever I try and use "https", "fetch", or "axios" modules to make an HTTP GET request I get errors (the same code works fine in a normal node environment, but I'm not a JS expert and can't seem to work past these errors). After a day of attempts it seems like the stored procedure approach is not possible.
Is this the case or is there some way of making HTTP GET requests from a JS stored procedure? If not possible with stored procedures, are there any other techniques to achieve the requirement of reading data from a remote API when querying cosmos DB?
Thanks
There is no way to achieve this from CosmosDB directly, for queries you also cannot use the change feed as the document dont change, so really your only option is to use a function or some preprocessor app to handle it, as you say its not ideal but there is no other solution here. If it was an insert or an update then change feed would allow you to do this but for plain queries its not possible.
I'm using nodejs to create an end to end test suite for our API. Before each test runs, I need to insert database records for that test. Many of the tables in question do not use native auto-increment type fields for their primary keys.
(I know, bad database design. But I don't have control over that.)
Instead, I have a Postgres database server to connect.
As I begin to set up my tests, I am finding that my transactions are colliding with each other because of the asynchronous nature of javascript. Basically, the transactions are getting the same sequence numbers and then trying to commit on top of each other. So unique constraints are failing.
The first solution that comes to my mind (I'm open to others) is to just set up all of the database records before any tests run. But to my knowledge, Jasmine's beforeAll() function only applies to the file that it's in. I need a beforeAll() function that runs before all Jasmine tests run in all files everywhere.
Does Jasmine have something like that? If not, is there a way I can create a controller in nodejs that will set up the test cases in the database and then spawn jasmine programmatically?
Thanks in advance!
I have a NightwatchJS test that requires a MSSQL Db call to complete before moving on to then verify the results of that db call. The test is 2 parts.
Part 1 fills out a form and submits it into our website and verifies via API in our CMS that the form successfully posted and saves the Guid in a table in another db specifically for Nightwatch testing for verification later.
Part 2 runs later in the day to allow another internal process to 'ingest' that form into a different department's db and return the ingestion results into our CMS for that form. Part 2 then needs to do a Db lookup into the Nightwatch db and get all Guids that happened in the last 24 hours and hit another API endpoint in our CMS to verify ingestion of that form occurred into that other department by checking a field that the other department's process updates on ingestion.
I had the same issue of waiting-to-complete with the API calls where I needed NightwatchJS to wait for the API call to complete in order to use the results in the assertion. To solve that, I used a synchronous http library called 'sync-request'. So, that part works fine.
However, I cannot seem to find a synchronous Db library that works in Nightwatch's world.
I am currently using 'tedious' as my Db library but there is no mechanism for awaiting. I tried promises and async/await to no avail since the async stuff is wrapped inside the library.
I tried Co-mssql but I keep getting an error
TypeError: co(...) is not a function
using their exact example code...
Any ideas or suggestions?
Any other synchronous MSSQL libraries that work in NightwatchJS?
Any way of using 'tedious' is a fashiopn that ensures await-ability?
I found a library called sync-request that blocks the thread which is what i need.
I'm developing APIs for social networking web application for learning perspective. When I started to write test cases I stuck around how to organize/write test cases.I'm initially proceeding like this:
First setup global data base initialization:
I need some users' auth tokens to test my routes so I decide to set up these information at global context. Also there are other information that also need to setup at global context so I'm setting that too.
Then for each route:
I start to write test cases and thought that I would write test cases in
such a way that each route test cases would be independent to each other.
and after completing all test suites:
I thought that I would clean up my data base.
The problems with this approach I'm facing are:
Say I want to test four routes named /users , /users/:id/my_invites , /send_invites, /response_invites. And further suppose I'm only interested in writing test cases for GET request and response for /users , /users/:id/invites and POSTing data in the case of others.
/send_invites, /response_invites definitely trigger some actions on the server side that modifies the data base state.
As we see that these routes effect the state of other routes' data say one user sends invites to another user and gets response true/false, so for that user his request was successful but how to ensure that another user actually received the invitation if we don't checking his received invitation documents(i.e through another route) in the first route test cases. Means /send_invites effects the /users/:id/my_invites .
because these routes are dependent on each others
So The questions I want to ask are:
how to write test cases for these routes so that each route would be independent ?
I tried with three dummy testing users in the global context and trying all sort of combinations for them in all test suites.My test suit presently deals with more than one routes to check 1 route true functionality.
Can anyone suggest me better solution for writing test cases for the above mentioned scenarios?
May be my question is too long or not clear. Please let me know and help me if you can.
My opinion:
First the bases EACH test case should have a fresh new state. That means that before you check one scenario, you want to flush your database and insert your new data prepared to test that case scenario. You can use a real database o mock one with data in-memory or however you prefer.
Second, each endpoint potentially affects a lot of tables in your database. So it's perfectly normal to check the state of your data, independently of the tables to check that the information is correct.
And well mocha and other test frameworks have functions that help you to do that. Like beforeEach and afterEach to set up and tear down your data before each test case.
How would I mock out the database in my node.js application, which in this case uses mongodb as the backend for a blog REST API ?
Sure, I could set the database to a specific testing -database, but I would still save data and not test my code only, but also the database, so I am actually not doing unit testing but integration testing.
So what should one do? Create database wrappers as a middle layer between application and db and replace the DAL when in testing?
// app.js
var express = require('express');
app = express(),
mongo = require('mongoskin'),
db = mongo.db('localhost:27017/test?auto_reconnect');
app.get('/posts/:slug', function(req, res){
db.collection('posts').findOne({slug: req.params.slug}, function (err, post) {
res.send(JSON.stringify(post), 200);
});
});
app.listen(3000);
// test.js
r = require('requestah')(3000);
describe("Does some testing", function() {
it("Fetches a blogpost by slug", function(done) {
r.get("/posts/aslug", function(res) {
expect(res.statusCode).to.equal(200);
expect(JSON.parse(res.body)["title"]).to.not.equal(null);
return done();
});
});
));
I don't think database related code can be properly tested without testing it with the database software. That's because the code you're testing is not just javascript but also the database query string. Even though in your case the queries look simple you can't rely on it being that way forever.
So any database emulation layer will necessarily implement the entire database (minus disk storage perhaps). By then you end up doing integration testing with the database emulator even though you call it unit testing. Another downside is that the database emulator may end up having a different set of bugs compared to the database and you may end up having to code for both the database emulator and the database (kind of like the situation with IE vs Firefox vs Chrome etc.).
Therefore, in my opinion, the only way to correctly test your code is to interface it with the real database.
There is a general rule of thumb when it comes to mocking which is
Don't mock anything you don't own.
If you want to mock out the database hide it behind an abstracted service layer and mock that layer. Then make sure you integration test the actual service layer.
Personally I've gone away from using mocks for testing and use them for top-to-bottom design helping me drive development from the top towards the bottom mocking out service layers as I go and then eventually implementing those layers and writing integration tests. Used as a test tool they tend to make your test very brittle and in the worst case leads to a divergence between actual behavior and mocked behavior.
I don't agree with the selected answer or other replies so far.
Wouldn't it be awesome if you could catch errors spawned by the chaotic and many times messy changes made to DB schemas and your code BEFORE it gets to QA? I bet the majority would shout heck yes!
You most certainly can and should isolate and test you DB schemas. And you don't do it based on an emulator or heavy image or recreation of you DB and machine. This is what stuff like SQLite is for just as one example. You mock it based on an in memory lightweight instance running and with static data that does not change in that in memory instance which means you are truly testing your DB in isolation and you can trust your tests as well. And obviously it's fast because it's in memory, a skeleton, and is scrapped at the end of a test run.
So yes you should and you should test the SCHEMA that is exported into a very lightweight in memory instance of whatever DB engine/runtime you are using, and that along with adding a very small amount of static data becomes your isolated mocked DB.
You export your real schemas from your real DB periodically (in an automated fashion) and import/update those into your light in memory DB instance before every push to QA and you will know instantly if any latest DB changes done by your DB admins or other developers who have changed the schema lately have broken any tests .
As for the person who replied with the "don't mock anything you don't own". I think he meant to say "don't test anything you don't own". But you DO mock things you do not own! Because those are the things not under test that need to be isolated!
This is what many test driven teams do all the time. You just have to understand the how.
My preferred approach to unit test DB code in any language is to access Mongo through a Repository abstraction (there's an example here http://iainjmitchell.com/blog/?p=884). Implementations will vary in terms of DB specific functionality exposed but by removing all the Mongo code from your own logic you're in a position to Unit Test. Simply replace the Mongo Repository implementation with a stubbed out version which is trivially easy. For instance, just store objects in a simple in-memory dictionary collection.
You'll get the benefits of unit testing your own code this way without DB dependencies but you'll still need to do integration tests against the main DB because you'll probably never be able to emulate the idiosyncrasies of the real database as others have said here. The kind of things I've found are as simple as indexing in safe mode vs without safe mode. Specifically, if you have a unique index your dummy memory implementation might honour that in all cases, but Mongo won't without safe-mode.
So whilst you'll still need to test against the DB for some operations, you'll certainly be able to unit test your own logic properly with a stubbed out Repository implementation.
The purpose of mocking is to skip the complexity and unit test own code. If you want to write e2e tests then use the db.
Writing code to setup/teardown a testing DB for unit testing is technical debt and incredibly unsatisfying.
There are mock libraries in npm:
mongo - https://www.npmjs.com/package/mongomock
mongoose - https://www.npmjs.com/package/mockgoose
If those don't support the features you need, then yes you may need to use the real thing.
I had this dilemma and chosen to work with a test DB and clean it every time the test begins. (how to drop everything: https://stackoverflow.com/a/25639377/378594)
With NPM you can even make a test script that creates the db file and cleans it up after.