I am building an app with locomotive.js, and I am looking to build my test suite using the Mocha test framework. I am also new to TDD/BDD in general, so please take that into consideration. I am curious if anyone can point me in a good direction to start testing a locomotive based app.
My biggest question would be:
How do I test a controller's actions?
Can I test an initializer?
Are there best practices around creating test request objects?
Testing controller actions
It depends on what exactly you want to test. Controller actions usually either return content, or pass (perhaps in case of errors) the request along the server stack, so testing them means using something like supertest to check for the correct responses (the supertest page also mentions how to use it together with Mocha)
Can I test an initializer?
Testing an initializer by itself is difficult, because they require to be run within the context of a LocomotiveJS application. However, you could create a test just booting up the application, which during the booting process will also run all initializers. I just added a simple Mocha-based testing framework to my Locomotive + Sequelize boilerplate project which shows how to boot the Locomotive app from within Mocha.
Are there best practices around creating test request objects?
If you mean how you can check responses to requests, look at the aforementioned supertest or perhaps mocha-headless.
Related
I am searching to write correct and understandable tests on react. I have read a lot of articles and texts. But I haven't understood a few matters. I have a component which request with axios. So there are requests like GET, POST.
How should the backend behave during frontend testing? Should the backend switch to test mode after frontend tests started ? Should the database reset itself after each frontend test ?
I think I shouldn't mock API to check if component correct render. What is the correct logic ?
The way that I approach this will be to mock the API call, the reason to do that will be, that I am reducing my scope of testing, As I am testing the React part, I would mock the success response and mock the error response and check how my components are working.
For the API testing, I will create a separate test case on the backend side. This way there will separation of concern. That is when I am testing react side I limit myself to the react side only and also this will make your test run fast as you are mocking the response, the actual request will not be sent and so you will get the response quickly.
I want to make integration tests in my node app. I have express endpoint, for example: POST: /users. This endpoint runs the User service to create a new user.
So I have the following dir structure:
routes
users
create.js // router.post('/users', ...);
services
users
create.js // actual user creation implementation
As you can see, the routes/users/create.js runs the services/users/create.js which does just anything and returns a response to the router and then the router sends back to the client.
I want to test it. As I said, should I test the route (using supertest or a kind) or the service or both?
As you may know there are three different types of tests:
Integration
End-to-end
Unit
Testing your router will cause the invocation of the other functions in your router and it'll go all the way through the path of calling everything! this is only in a scenario where you use everything as is and don't create mock or spy for those functions.
Testing a router is more of an End-To-End testing than unit testing.
If you want to use any sort of fakes (mock, spy) then you have to be careful since not always you're allowed to do it ( if you basically have an unmanaged dependency like a shared database between more than one service. you can only use fakes in this scenario ). other than that using mocks brings test fragility and violates resistance to regression (how much code/branches you've covered) and resistance to refactoring (how likely it is if you change any code your test breaks).
So testing routers is basically integration testing, not unit testing and is possible!
I am developping a RESTful Node.js API (express+mongoose)
This API calls a third party Oauth API (google, facebook, whatever).
I've been quite happy setting up automated testing with mocha+chai+request so far, but I'm having trouble mocking the third party API to test the route (of my API) that calls it.
I've tried using nock, but it doesn't work for my use case.
To run my tests, I start my API (npm start), and in another tab, I start the test suite (npm test). The test suite uses request to test the API over HTTP.
Hence I think nock doesn't work here because it is mocking http in the 'test suite' process and not in the 'API' process.
I absolutely need to mock this third party call for 2 reasons:
1. I want to be able to run my test suite offline with everything running on my laptop
2. Since the third party API uses Oauth, hard coding credentials in the test suite (even for a test account) doesn't seem too easy.
I would really love not to leave this giant hole in my test coverage, so any advice would be much apreciated!
so this is how I solve my own problem. I came up with it on my own while setting up proper testing for an app for the first time so feel free to suggest improvements. Disclaimer: I use coffee script
The first step was to launch my app from another file, starter.coffee, that essentially looks like this:
# This file starts the API locally
require './test/mocks/google_mock'
require './app'
So to start my server for tests, instead of doing coffee app.coffee, I would do coffee starter.coffee.
The google_mock.coffee file mocks the Google API before the app is launched from the app.coffee file.
For that I use the nock! package.
The google_mock.coffee files looks like this:
nock = require 'nock'
# mocking up google api
googleapis = nock('https://www.googleapis.com')
.get('/userinfo/v2/me')
.reply(401)
with a lot more lines for mocking other Google api calls.
I am using LocomotiveJS to build an MVC application. I have been thinking about the type of tests I should write and am confused.
Here are the different components in the application - Models, Views, Controllers, Router and the ORM.
If I had to unit test every component, here is how I think I should approach it.
Write tests to ensure the API provided by ORM act the way I expect it to.
Unit test my Model stubbing the ORM. I provide it the stub so I do not have to rely on actual database operations in my unit test.
A Controller accesses Views and Models. A Controller's job is to get/modify the model and to respond to the client (render/redirect).
The controller's response can be tested by providing them test inputs and checking if the right response is generated (stub out render/redirect and make sure the right calls are made).
Model manipulation by the controller can be tested by stubbing out the model and ensuring the right calls are made. This feels wrong, since I am testing the implementation...
Views are just templates; the controller binds the templates with values. I could create a fake view model and bind it to the view and see if the right output is generated.
Routes just take the request and map it to the right Controller and Action. I can ensure the right routes are supported by the app by stubbing out parts of the Router and making sure a request to the router is mapped to the expected Controller/Action.
Say I change a model API now, I have to change the model test, I have to change the model stubs used by the controller test and I have to update the assertions in controller test.
This seems like overkill.
Does this rather make sense?
Do 1 and 2 as above.
3. Integration test the rest (Controller/View/Router). Here I think I should just start up my app in a test environment and use supertest to ensure the requests generate the right responses - visiting an url, I get the right content, right redirects etc.
I think it makes sense to unit test the model because it represents an interaction with a different system (data persistence). We want to make sure the bridge functions properly. Router/Controller/View interact within our own system and in very specific ways. So it seems okay to integration test that. What are your thoughts?
If you rely on integration tests, you will lose the benefits of unit tests. Your tests will run more slowly than they need to and will therefore be run less often. Your tests will not tell you where you broke something. Your tests will not exercise as much of the functionality of the application. Your tests will be only half as effective as documentation. You will not be able to TDD.
Overall, any time someone chooses to forgo unit tests in the interest of speed, they go more slowly.
For my application i have used solr-node client
How can i write unit tests by mocking the calls to the solr module?
Can someone pls help me out of this?
Try using JsMockito - it's a JavaScript based mocking framework that allows you to mock up objects, function calls, and returns in your project.