Skip to content

Commit

Permalink
docs: add stub service section
Browse files Browse the repository at this point in the history
  • Loading branch information
biniam committed May 15, 2019
1 parent b87f0be commit 63efd01
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
61 changes: 58 additions & 3 deletions docs/site/Testing-your-application.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,17 +408,72 @@ Verify how was the stubbed method executed at the end of your unit test (in the
```ts
// expect that repository.find() was called with the first
// argument deeply-equal to the provided object
sinon.assert.calledWithMatch({where: {id: 1}});
sinon.assert.calledWithMatch(findStub, {where: {id: 1}});
```

See [Unit test your controllers](#unit-test-your-controllers) for a full
example.

#### Create a stub Service

{% include content/tbd.html %}
If your controller relies on service proxy for service oriented backends such as
REST APIs, SOAP Web Services, or gRPC microservices, then we can create stubs
for the service akin to the steps outlined in the above
[stub repository](#create-a-stub-repository) section. Consider a dependency on a
`GeoCoder` service that relies on a remote REST API for returning coordinates
for a specific address.

The initial beta release does not include Services as a first-class feature.
```ts
export interface GeocoderService {
geocode(address: string): Promise<GeoPoint[]>;
}
```

The first step is to create a mocked instance of the `GeocoderService` API and
configure its `geocode` method as a Sinon stub:

```ts
describe('GeocoderController', () => {
let geoService: GeoCoderService;
let geocode: sinon.SinonStub;

beforeEach(givenMockGeoCoderService);

// your unit tests

function givenMockGeoCoderService() {
// this creates a stub with GeocoderService API
// in a way that allows the compiler to verify type correctness
geoService = {geocode: sinon.stub()};

// this creates a reference to the stubbed "geocode" method
// because "geoService.geocode" has type from GeocoderService
// and does not provide Sinon APIs
geocode = geoService.geocode as sinon.SinonStub;
}
});
```

Afterwards, we can configure the `geocode` stub's behaviour before the `act`
phase of our test(s):

```ts
// geoService.geocode() will return a promise that
// will be resolved with the provided array
geocode.resolves([<GeoPoint>{y: 41.109653, x: -73.72467}]);
```

Lastly, we'll verify how the stub was executed:

```ts
// expect that geoService.geocode() was called with the first
// argument equal to the provided address string
sinon.assert.calledWithMatch(geocode, '1 New Orchard Road, Armonk, 10504');
```

Check out
[TodoController unit tests](https://github.com/strongloop/loopback-next/blob/bd0c45033503f631a533ad6176620354d9cf6768/examples/todo/src/__tests__/unit/controllers/todo.controller.unit.ts#L53-L71)
illustrating the above points in action for more information.

### Unit test your Controllers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe('TodoController', () => {

expect(result).to.eql(expected);
sinon.assert.calledWith(create, input);
sinon.assert.calledWith(geocode, input.remindAtAddress);
});
});

Expand Down

0 comments on commit 63efd01

Please sign in to comment.