我已经关注了the documentation about using graphql-tools to mock a GraphQL server,但这会导致自定义类型出错,例如:
Expected a value of type "JSON" but received: [object Object]
有关模拟的graphql-tools文档明确声明它们支持自定义类型,甚至提供了使用graphql-type-json项目中的GraphQLJSON自定义类型的示例。
我提供a demo of a solution on github使用graphql-tools成功模拟GraphQL服务器,但这依赖于猴子修补构建的模式:
// Here we Monkey-patch the schema, as otherwise it will fall back
// to the default serialize which simply returns null.
schema._typeMap.JSON._scalarConfig.serialize = () => {
return { result: 'mocking JSON monkey-patched' }
}
schema._typeMap.MyCustomScalar._scalarConfig.serialize = () => {
return mocks.MyCustomScalar()
}
可能我在我的演示中做错了什么,但如果没有上面提到的猴子修补代码,我会收到有关上述自定义类型的错误。
有没有人比我的演示有更好的解决方案,或者我可能做错什么的任何线索,以及我如何更改代码以便演示可以在没有猴子修补架构的情况下工作?
演示index.js
中的相关代码如下:
/*
** As per:
** http://dev.apollodata.com/tools/graphql-tools/mocking.html
** Note that there are references on the web to graphql-tools.mockServer,
** but these seem to be out of date.
*/
const { graphql, GraphQLScalarType } = require('graphql');
const { makeExecutableSchema, addMockFunctionsToSchema } = require('graphql-tools');
const GraphQLJSON = require('graphql-type-json');
const myCustomScalarType = new GraphQLScalarType({
name: 'MyCustomScalar',
description: 'Description of my custom scalar type',
serialize(value) {
let result;
// Implement your own behavior here by setting the 'result' variable
result = value || "I am the results of myCustomScalarType.serialize";
return result;
},
parseValue(value) {
let result;
// Implement your own behavior here by setting the 'result' variable
result = value || "I am the results of myCustomScalarType.parseValue";
return result;
},
parseLiteral(ast) {
switch (ast.kind) {
// Implement your own behavior here by returning what suits your needs
// depending on ast.kind
}
}
});
const schemaString = `
scalar MyCustomScalar
scalar JSON
type Foo {
aField: MyCustomScalar
bField: JSON
cField: String
}
type Query {
foo: Foo
}
`;
const resolverFunctions = {
Query: {
foo: {
aField: () => {
return 'I am the result of resolverFunctions.Query.foo.aField'
},
bField: () => ({ result: 'of resolverFunctions.Query.foo.bField' }),
cField: () => {
return 'I am the result of resolverFunctions.Query.foo.cField'
}
},
},
};
const mocks = {
Foo: () => ({
// aField: () => mocks.MyCustomScalar(),
// bField: () => ({ result: 'of mocks.foo.bField' }),
cField: () => {
return 'I am the result of mocks.foo.cField'
}
}),
cField: () => {
return 'mocking cField'
},
MyCustomScalar: () => {
return 'mocking MyCustomScalar'
},
JSON: () => {
return { result: 'mocking JSON'}
}
}
const query = `
{
foo {
aField
bField
cField
}
}
`;
const schema = makeExecutableSchema({
typeDefs: schemaString,
resolvers: resolverFunctions
})
addMockFunctionsToSchema({
schema,
mocks
});
// Here we Monkey-patch the schema, as otherwise it will fall back
// to the default serialize which simply returns null.
schema._typeMap.JSON._scalarConfig.serialize = () => {
return { result: 'mocking JSON monkey-patched' }
}
schema._typeMap.MyCustomScalar._scalarConfig.serialize = () => {
return mocks.MyCustomScalar()
}
graphql(schema, query).then((result) => console.log('Got result', JSON.stringify(result, null, 4)));
答案 0 :(得分:0)
我和其他一些人看到了与实时数据源类似的问题(在我的例子中是MongoDB / Mongoose)。我怀疑它是graphql-tools makeExecutableSchema内部的东西,以及它使用自定义类型摄取基于文本的模式的方式。
此处有关该问题的另一篇文章:How to use graphql-type-json package with GraphQl
我还没有尝试过在代码中构建架构的建议,因此无法确认它是否有效。
我目前的解决方法是在向客户端提供JSON字段(在连接器中)时对其进行字符串化(并在客户端进行解析),反之亦然。有点笨重,但我并没有真正使用GraphQL来查询和/或有选择地提取JSON对象中的属性。对于我怀疑的大型JSON对象,这不是最佳选择。
答案 1 :(得分:-1)
如果其他人来自Google搜索结果,我的解决方案是将JSON解析程序作为参数添加到makeExecutableSchema
调用中。它在这里描述:
https://github.com/apollographql/apollo-test-utils/issues/28#issuecomment-377794825
这让我的嘲笑工作。