Skip to content

Commit

Permalink
Examples of a simplified and more easily achievable form of automated…
Browse files Browse the repository at this point in the history
… contract testing.
  • Loading branch information
ashleydavis committed Jul 21, 2024
0 parents commit 2a29896
Show file tree
Hide file tree
Showing 28 changed files with 21,679 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/contract-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Automated contract tests

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

jobs:
contract-tests:
runs-on: ubuntu-latest

strategy:
matrix:
subproject:
- rest-api
- mocked-mongodb
- mocked-rabbit

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: v20

- run: npm ci
working-directory: ${{ matrix.subproject }}
- run: npm test
working-directory: ${{ matrix.subproject }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# simplified-contract-testing

Examples of a simplified and more easily achievable form of automated contract testing:

- rest-api/ An example of contract testing against an existing REST API.
- mocked-mongodb/ An example of contract testing a REST API with a mock database.
- mocked-rabbit/ An example of contract testing a REST API and asynchronous messaging with a mock RabbitMQ.

See README files in subdirectories to learn how to run each example.

You need Node.js installed to run these examples.
45 changes: 45 additions & 0 deletions mocked-mongodb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# mocked-mongodb

An example of simplified contract testing against a REST API that is backed by a MongoDB database.

The REST API is based on JSON Placeholder: https://jsonplaceholder.typicode.com/

Built on:
- Express.js to implement the REST API.
- MongoDB for the database.
- Jest for running the tests and matching expectations.
- Jest is used to mock MongoDB for the automated contract tests.
- Axios for making the HTTP requests.
- Jest-json-schema and Ajv for testing the REST API response against the JSON schema in the test spec.
- Yaml for parsing the test spec.

## Test spec

See the test spec here: [./test/test-spec.yaml](./test/test-spec.yaml).

See the contract testing code here: [./test/contract.test.js](./test/contract.test.js).

## Setup

```bash
git clone [email protected]:ashleydavis/simplified-contract-testing.git
cd simplified-contract-testing/mocked-mongodb
npm install
```

## Run tests

```bash
npm test
```

Note: Testing uses a mocked version of MongoDB.

## Run the REST API

```bash
npm start
```

Note: This includes an instant development database.

69 changes: 69 additions & 0 deletions mocked-mongodb/__mocks__/mongodb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// A mock version of the MongoDB library.
//

let data = {};

class ObjectId {
constructor(value) {
this.__value = value;
}

toString() {
return this.__value;
}

toJSON() {
return this.__value;
}
}

class MongoCollection {
constructor(collectionName) {
this.collectionName = collectionName;
}

async findOne({ _id }) {
const collectionData = data[this.collectionName] || [];
return collectionData.find(el => el._id.__value === _id.__value);
}

find() {
return {
async toArray() {
return data[this.collectionName] || [];
}
}
}

async insertOne() {
return {
insertedId: new ObjectId("newly-inserted"),
};
}
}

class MongoDatabase {
collection(collectionName) {
return new MongoCollection(collectionName);
}
}

class MongoClient {
async connect() {
}

db() {
return new MongoDatabase();
}
}

function __setData__(_data) {
data = _data;
}

module.exports = {
MongoClient,
ObjectId,
__setData__,
};
Loading

0 comments on commit 2a29896

Please sign in to comment.