Closed DHFW closed 4 years ago
You can use the resolve method to skip the db query and mock the db result.
@koskimas Thanks for the quick response. However, do you have an example how to implement this in a simple unit test? How do I go about this when I want to spy/mock on just say one findById request?
Yeah, I'd love to +1 @DHFW's most recent comment. Specifically,
if I already have calls to Model.query().select().join()
in my server code, is there any cleaner way to mock the entire call in some unit test? Or will @DHFW's first post have to suffice?
You can override the model's query()
method so that it returns a query builder calling resolve()
with whatever value you like. There's some more info about this in the docs here: https://vincit.github.io/objection.js/recipes/custom-query-builder.html#custom-query-builder-extending-the-query-builder
Thanks @devinivy. Does this mean that I either need to go and edit my DB code so that it calls the resolve()
function? As in, there is no in-place mock? Or, are you suggesting that I can completely mock out query()
with resolve()
and everything will be fine?
The reason I'd like to clarify is that query()
is often the first in a chain of calls. Mocking query()
to return the result of resolve()
instead, when there are still chained calls after query()
, seems like it will break anything chained onto query()
.
It should work just fine without modifying any application code! As the docs show, queryBuilder.resolve()
returns queryBuilder
, so you can keep chaining :) https://vincit.github.io/objection.js/api/query-builder/other-methods.html#resolve
Oh damn! Amazing! Thanks so much for pointing that out. This is a huge plus for the community because this just makes server testing so much easier now. Thank you all!
For anyone stumbling upon this from hapi/hapipal/schwifty land, here's an example for a route handler:
// route handler
const { Person } = request.models(true);
const person = await Person.query().findById(request.params.id);
// test with stub
import { QueryBuilder } from 'objection';
const { Person } = server.models(true); // or import Person from '../wherever/models/Person';
Sinon.stub(server.models(true), 'Person').value({
query: () => QueryBuilder.forClass(Person).resolve({ id: 111 }),
});
I have found that mock-knex offers the most complete experience for mocking and asserting the queries. :orange_circle: :orange_circle:
@lucasrcosta How are you injecting the mock-knex instance? I can't figure it out.
For unit testing and mocking of database calls I use the following:
This works pretty well for me (ObjectionJS version: 1.6.8) with Jest 24. I wonder what your code looks like? We don't have so much help from TypeScript here (using everything as
any
because the models have so many properties and methods), so any ;) suggestions are welcome!