graphql-tools icon indicating copy to clipboard operation
graphql-tools copied to clipboard

Bug(mock): Resolver with return type List is not use value from mock resolver.

Open IttisutBm opened this issue 4 years ago • 0 comments

// server.js
const server = new ApolloServer({
  ...
  mockEntireSchema: false,
});

// schema.gql
type User {
   id: ObjectId
   username: String
   nickname: String
}

// mocks.js
export default {
    User(){
       nickname: 'John'
    }
   String: ()=>'Bob'
}

// resolvers.js
export default {
    Query: {
        // Both of query get Object type User with `undefined` value on `nickname` prop
        // `user resolver` is working correctly. it return user with nickname `John`
        user:(root, {id}, { db })=>db.get('user').find({ id }).value() 
        // `users resolver` is wrong. it return user with nickname `Bob`
        users:(root, args, { db })=>db.get('user').value()  
}

I found that we can fix this by edit this function:

https://github.com/ardatan/graphql-tools/blob/b8308efe906bfed02391a97c6f6699c66e71f1ff/packages/mock/src/addMocksToSchema.ts#L180-L206

In case of return type List, it will go to this line.

https://github.com/ardatan/graphql-tools/blob/b8308efe906bfed02391a97c6f6699c66e71f1ff/packages/mock/src/addMocksToSchema.ts#L205

This mean it will return list value from resolver and ignore list value from mock resolver which is wrong. We need to merge value from resolver and mock server together and it done. I add this code above that line and it work!.

if(Array.isArray(mockedValue) && Array.isArray(resolvedValue)){
    const results = []
    resolvedValue.forEach(function(element,index,array) {
        const emptyObject = Object.create(Object.getPrototypeOf(resolvedValue[index]));
        results.push(copyOwnProps(emptyObject, resolvedValue[index], mockedValue[index]))
    })
    return results;
}

I'm not quite sure. this is the right approach or not. Hope it help. 😄

IttisutBm avatar Feb 04 '21 21:02 IttisutBm