Reputation: 722
I created a mock programmatically for testing at my query but it only returns a null value what am i doing wrong. I am using the casual library for generating values for my mock
Here are my files:
index.js
import express from 'express'
import bodyParser from 'body-parser'
import { graphqlExpress,graphiqlExpress } from 'graphql-server-express'
import { makeExecutableSchema } from 'graphql-tools'
import mock from './mock'
import schema from './schema'
const app = express()
const executableSchema = makeExecutableSchema({
typeDefs: schema,
mock
})
app.post(
'/graphql',
bodyParser.json(),
graphqlExpress(() => ({
schema: executableSchema
}))
)
app.use('/graphiql',graphiqlExpress({
endpointURL: '/graphql',
}))
app.listen(8080)
console.log("listening at 8080")
schema.js
const schema = `
interface Novel {
artist: String
author: String
chapters: [Chapter]
description: String
genre: [String]
id: String
image: String
language: String
modified: String!
name: String!
status: String
tags: [String]
type: String
year: String
}
interface Chapter {
chapter: String!
volume: String!
content: String!
}
type NovelCrawler implements Novel{
artist: String
author: String
chapters: [Chapter]
description: String
genre: [String]
id: String
image: String
language: String
modified: String!
name: String!
novelurl: String
status: String
tags: [String]
type: String
year: String
}
type ChapterCrawler implements Chapter {
chapter: String!
chapterurl: String
content: String!
novelurl: String
volume: String!
}
`
const Query = `
type Query {
novels: [Novel]
}
`
export default [schema, Query]
mock.js
import casual from 'casual'
const genre = ['romance', 'comedy', 'action']
const Novel = () => ({
artist: casual.name,
author: casual.name,
description: casual.sentences(3),
genre: [casual.random_element(genre), casual.random_element(genre)],
id: casual.url,
image: 'sdfgrtw3wedfgb2345y675trfdvfbghdsfdssfd',
language: casual.random_element(['chinese', 'japanese', 'korean']),
modified: casual.date('YYYY-MM-DD'),
name: casual.word,
status: casual.random_element(['Completed', 'Ongoing']),
tags: [],
novelurl: casual.url,
type: casual.random_element(['Web Novel', 'Light Novel']),
year: casual.year
})
const Chapter = () => ({
chapter: casual.integer(1, 50),
chapterurl: casual.url,
content: casual.sentences(10),
novelurl: casual.url,
volume: casual.integer(1, 5)
})
const arrNovel = []
const arrChapter = []
for (let x = 0; x < 20; ++x) {
arrNovel.push(Novel())
arrChapter.push(Chapter())
}
const mock = {
// Query: { novels: () => ({}) },
Novel: {
__resolveType(obj, context, info) {
return 'NovelCrawler'
}
},
Chapter: {
__resolveType(obj, context, info) {
return 'ChapterCrawler'
}
},
NovelCrawler: () => arrNovel,
ChapterCrawler: () => arrChapter
}
export default mock
When i run the following query:
{
novels{
description
}
}
it returns:
{
"data": {
"novels": null
}
}
so i tried:
{
novels{
... on NovelCrawler{
artist
}
}
}
this returns
{
"errors": [
{
"message": "Unknown operation named \"null\"."
}
]
}
what am i doing wrong
Upvotes: 0
Views: 2129
Reputation: 84867
Thanks for providing complete code and examples. Here's a few notes to get you going in the right direction:
Make sure you are implementing mocks correctly. I think makeExecutableSchema
used to accept a mocks option at one point, but now you have to use addMockFunctionsToSchema
in conjunction with it to implement mocking. I would read Apollo's guide to mocking for detailed steps on how to do that.
graphqlExpress
is actually middleware, so you should implement it with app.use
instead of app.post
. GraphQL Server can handle both POST and GET requests.
You probably don't need interfaces for what you're trying to do. An interface requires that every type that implements it also has the fields defined in the interface. They're used when two or more types share fields, which isn't the case here. I would suggest making Chapter
a regular type and nesting it inside ChapterCrawler
like below. Ditto for Novel.
type ChapterCrawler {
chapter: Chapter!
chapterurl: String
novelurl: String
}
type Chapter {
chapter: String!
content: String!
volume: String!
}
If you go with the above method, you will need to eventually change your query to fetch [NovelCrawler]
instead. Wait! Before making things more complicated and harder to debug, I would suggest mocking just Chapter
and adding a query to get [Chapters]
first. Once you have that working, you'll know you have the basic functionality down and can starting mocking and querying more complex data structures.
If you do need interfaces, make sure you get what function they serve and how to correctly implement them. This article may help clarify things.
Keep in mind makeExecutableSchema
takes typeDefs and resolvers separately once you're no longer mocking everything.
Upvotes: 3