Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing microservices in node.js

Testing microservices in node.js

Microservice architecture is becoming an increasingly popular choice among platform architects, and for good reason: when implemented correctly, it can increase team velocity, facilitate technological diversity, and enforce good abstractions. However, writing good tests for a microservice-based platform is often a tough task, due to the complexity of the interactions between services and of the system as a whole.

In this talk, Justin will present an introduction to microservice architecture, as well as an overview of the various types of automated test suites and their place in conventional application development. He will then discuss the role of each type of test in the context of microservice-based systems, and will close with a number of recommendations for writing efficient and effective tests. Along the way, Justin will highlight various JavaScript tools that are helpful when writing tests for Node.js applications and microservices.

Justin Bachorik

November 02, 2018
Tweet

More Decks by Justin Bachorik

Other Decks in Technology

Transcript

  1. justinbach What we’ll cover 1. Testing: why and how? 2.

    Overview of microservice architecture 3. Testing microservices in node.js
  2. justinbach Failing unit tests as bug reports 1. Which component

    is being tested? 2. What behavior is being tested? 3. What are the actual results? 4. What are the expected results? 5. How can the actual results be reproduced? https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d
  3. justinbach Backend duties • User management • Dog inventory •

    Walk scheduling • Business reporting • Notifications • Client app API • Business API
  4. justinbach Advantages of microservices • Separation of concerns • Smaller,

    faster deployments • Technological heterogeneity • Resilience See https://martinfowler.com/articles/microservice-trade-offs.html for more
  5. justinbach A sample route GET /dogs [{ name: “Biscuit”, id:

    “df724ea3-beb8-4c97-a6a5-32acaba7bbad”, photo: “https://cdn.dogpool.com/img/b87f8fcd.jpg” }, // … more dogs? ]
  6. justinbach Method under test const findByUserId = async (db, userId)

    => { if (!userId) { throw new Error('findByUserId: must specify userId'); } return db.query(Sql.FIND_BY_USER, userId); };
  7. justinbach Example: unit test describe('findByUserId', () => { it('should return

    dogs belonging to the user', async () => { await insertTestData(db, expectedData); // arrange const actualData = await Dog.findByUserId(db, userId); // act expect(actualData).to.deep.equal(expectedData); // assert await reset(db); }); });
  8. justinbach Unit tests... • ...exhaustively test methods, one code-path at

    a time • ...live alongside the code under test • ...are run on every commit and PR • ...tend to be more white-box than other tests
  9. justinbach Unit tests: tools 1. Testing framework (Mocha, Jest, Jasmine,

    Ava, Tape) 2. Assertion library (Assert, Should, Expect, Chai) 3. Mocking plugin (Sinon) 4. Coverage reporter (Istanbul, NYC)
  10. justinbach Service integration tests... • ...exercise the full request cycle

    at the microservice level • ...validate routing and middleware configuration • ...are run on every commit and PR • ...are gray-box (requests to upstream services are mocked)
  11. justinbach Example: service integration test describe('GET /dogs?userId={userId}', () => {

    it('should return 200 and the correct dogs', async () => { const actualResponse = await request(app) .get(`/dogs?userId=${userId}`) .expect(200); expect.actualResponse.to.deepEqual(expectedResponse); }); });
  12. justinbach Platform integration tests... • ...can reside in Public API

    or an external repository • ...are run against a full staging environment • ...are completely black-box (except external service mocks)
  13. justinbach 1. Testing framework (Mocha, Jest, Jasmine, Ava, Tape) 2.

    Assertion library (Assert, Chai, Should, Expect) 3. Request library (request-promise, fetch) 4. Service-mocking tool (WireMock) Platform integration tests: tools
  14. justinbach Example: platform integration test describe('GET /dogs', () => {

    it('should return the current user’s dogs', async () => { const options = { method: 'GET', url: `${host}/dogs`, headers: `Bearer ${token}` }; const actualResponse = await rp(options); expect.actualResponse.to.deepEqual(expectedResponse); }); });