Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
IttisutBm opened this issue Feb 4, 2021 · 0 comments

Comments

@IttisutBm
Copy link

IttisutBm commented Feb 4, 2021

// 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:

newFieldConfig.resolve = async (rootObject, args, context, info) => {
const [mockedValue, resolvedValue] = await Promise.all([
mockResolver(rootObject, args, context, info),
oldResolver(rootObject, args, context, info),
]);
// In case we couldn't mock
if (mockedValue instanceof Error) {
// only if value was not resolved, populate the error.
if (undefined === resolvedValue) {
throw mockedValue;
}
return resolvedValue;
}
if (resolvedValue instanceof Date && mockedValue instanceof Date) {
return undefined !== resolvedValue ? resolvedValue : mockedValue;
}
if (isObject(mockedValue) && isObject(resolvedValue)) {
// Object.assign() won't do here, as we need to all properties, including
// the non-enumerable ones and defined using Object.defineProperty
const emptyObject = Object.create(Object.getPrototypeOf(resolvedValue));
return copyOwnProps(emptyObject, resolvedValue, mockedValue);
}
return undefined !== resolvedValue ? resolvedValue : mockedValue;
};

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

return undefined !== resolvedValue ? resolvedValue : mockedValue;

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. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant