HoukasaurusRex / boilerplate-express-ts-server

A Best Practices™️ Express.js and Typescript server with clustering and socket.io
https://perfect-express-ts-server.herokuapp.com/
MIT License
4 stars 1 forks source link

Thoughts on testing strategy #7

Closed TNieminen closed 4 years ago

TNieminen commented 4 years ago

Should this repo encourage a certain way of unit/integration testing? Should this be documented in the README? Since the goal seems to be to have an opinionated view into express server development it could be in place.

Here are some thoughts on the topic:

Integration tests

In the repository this example is inspired by, all tests are really integration tests and there are no real unit tests. As in any API test will have to

  1. Spin up the server
  2. Seed the database
  3. Call an API and evaluate response

and during this operation we have many other imported functions and database queries that have to work perfectly together. There is nothing wrong with this per-se (even though maybe it could be improved or simplified), but it could be argued that those type of tests should be moved under the integration tests folder

Unit testing

There could be a way to split every task into a separate unit-testable function and take testing "as close to iron as possible". This would include

  1. Testing any functionality, be that a API provider or a service as a simple function with an input, output and maybe side effects
  2. Mock all dependencies and other used functions
  3. Mock all possible inputs (like request or response objects)
  4. Test for valid outputs
  5. Test for side effects and that external function calls have been called with proper parameters

In a OOP paradigm this is rather simple to achieve with something like

// mocks
classInstance.doTaskB = jest.fn()
// run function
const returnValue =classInstance.toTaskAAndCallB()
// evaluate response
expect(returnValue).toEqual(something)
expect(classInstance.doTaskB).toHaveBeenCalledWith(something)

This can be more tricky for functional programming, but there are ways such as import mocking discussed here

This will require some thinking to accomplish, but if we were to do this we should accomplish easy to write and maintain unit tests for the project.

HoukasaurusRex commented 4 years ago

Agreed, I believe I have an example test in each folder for unit and integration tests. The integration tests run the familiar supertest against the express app.js, while the the unit test folder so far only tests service functions in the services folder. I don't want to encourage overtesting, so my thinking right now is that for the most part integration tests are most useful against the apis (does this api do what I expect) and unit tests are most useful against service/utility functions (does this function return what I expect)

TNieminen commented 4 years ago

My broader point on the testing strategy might need some playing around. I might propose this later again once I schedule some time to test it myself.