graphql tools
In my last article, I took the original Apollo LaunchPad Posts and Authors API and broke it down into domains and components. I wanted to illustrate how one could organize a large GraphQL project using graphql-tools.
在上一篇文章中,我采用了原始的Apollo LaunchPad Posts and Authors API,并将其细分为域和组件。 我想说明一个人如何使用graphql-tools组织一个大型GraphQL项目。
Now I’d like the API to return mock data when I query it. How?
现在,我希望API在查询时返回模拟数据。 怎么样?
In the original Apollo Launchpad example, we used static data structures and simple mapping resolvers to provide output for queries.
在原始的Apollo Launchpad示例中,我们使用了静态数据结构和简单的映射解析器来提供查询的输出。
For instance, given this query:
例如,给定此查询:
# Welcome to GraphiQL
query PostsForAuthor {
author(id: 1) {
firstName
posts {
title
votes
}
}
}
The output would be:
输出为:
{
"data": {
"author": {
"firstName": "Tom",
"posts": [
{
"title": "Introduction to GraphQL",
"votes": 2
}
]
}
}
}
The resolvers object has functions that take care of mapping authors to posts and visa-versa. It’s not truly a mock, though.
解析器对象具有负责将作者映射到帖子,反之亦然的功能。 但是,这并不是真正的模拟。
The problem is that the more relationships and the more complex the entities become, the more code needs to go into the resolvers. Then more data needs to be provided.
问题在于,实体之间的关系越多,越复杂,则需要更多的代码输入解析器。 然后,需要提供更多数据。
When it comes to testing, tests are likely to sometimes reveal problems in the data or in the resolvers. You really want focus testing of the API itself.
对于测试,测试有时可能会揭示数据或解析器中的问题。 您确实要对API本身进行焦点测试。
There are three Node.js modules that make mocking an API quick and easy. The first is part of the graphql-tools
module. Using this module, a beginning step is to require or import the method addMockFunctionsToSchema
from the module into the root schema.js
file:
通过三个Node.js模块,可以快速轻松地模拟API。 首先是graphql-tools
模块。 使用此模块,第一步是要求或导入方法addMockFunctionsToSchema
从模块到根schema.js
文件:
import {
makeExecutableSchema,
addMockFunctionsToSchema
} from 'graphql-tools';
Then, after creating an executable schema
by calling createExecutableSchema
, you add your mocks like so:
然后,在通过调用createExecutableSchema
创建可执行schema
之后, 您可以这样添加模拟:
addMockFunctionsToSchema({
schema: executableSchema,
})
Here’s a full listing of the root schema.js
:
这是根schema.js
的完整列表:
So what’s the output? Executing the same query as before yields:
那么输出是什么? 执行与之前相同的查询会产生:
{
"data": {
"author": {
"firstName": "Hello World",
"posts": [
{
"title": "Hello World",
"votes": -70
},
{
"title": "Hello World",
"votes": -77
}
]
}
}
}
Well, that’s kind of dumb. Every string is “Hello World”, votes are negative, and there will always be exactly two posts per author. We’ll fix that, but first…
好吧,这真是愚蠢。 每个字符串都是“ Hello World”,票数是否定的,每个作者始终只有两个帖子。 我们将解决此问题,但首先…
Mocks are often used in unit tests to separate the functionality being tested from the dependencies that those functions rely on. You want to test the function (the unit), not a whole complex of functions.
模拟通常用于单元测试中,以将要测试的功能与这些功能所依赖的依赖项区分开。 您要测试功能(单元),而不是功能的整体。
At this early stage of development, mocks serve another purpose: to test the tests. In a basic test, you want to ensure first that the test is calling the API correctly, and that the results returned have the expected structure, properties, and types. I think the cool kids call this “shape”.
在开发的早期阶段,模拟服务的另一个目的是:测试测试。 在基本测试中,您首先要确保测试正确调用了API,并且返回的结果具有预期的结构,属性和类型。 我认为很酷的孩子称之为“形状”。
This offers more limited testing than a queryable data structure, because reference semantics are not enforced. id
is meaningless. Nonetheless, mocks offer something to structure your tests around
与可查询的数据结构相比,这提供了更多有限的测试,因为没有强制执行引用语义。 id
是没有意义的。 尽管如此,模拟还是提供了一些结构化测试的方法
There’s a module called casual that I really like. It provides reasonable and variable values for a lot of common data types. If you are demonstrating your new API in front of jaded colleagues, it actually looks like you’ve done something special.
我真的很喜欢一个叫做休闲的模块。 它为许多常见数据类型提供了合理且可变的值。 如果您是在厌倦的同事面前演示新的API,那么实际上看起来您已经做了一些特别的事情。
Here’s a wish list for mock values to display:
这是要显示的模拟值的愿望清单:
Author’s first name should be first-name-like
作者的名字应该像名字一样
Post titles should be variable lorem ipsum text of limited length
帖子标题应为长度有限的可变lorem ipsum文本
First thing is to create a folder called mocks
. Next, we’ll add an index.js
file to that folder with the mock methods. Finally, the custom mocks will be added to the generated executable schema.
第一件事是创建一个名为mocks
的文件夹。 接下来,我们将使用模拟方法将index.js
文件添加到该文件夹。 最后,自定义模拟将添加到生成的可执行模式中。
The casual library can generate values by data type (String, ID, Int, …
) or by property name. Also, graphql-tools MockList object will be used to vary the number of items in a list — in this case posts
. So let’s start.
临时库可以按数据类型( String, ID, Int, …
)或属性名称生成值。 此外,graphql-tools MockList对象将用于更改列表中的项目数(在本例中为posts
。 因此,让我们开始吧。
Import
both casual and MockList into /mocks/index.js
:
Import
既休闲又MockList到/mocks/index.js
:
import casual from 'casual';
import {
MockList
} from 'graphql-tools';
Now let create a default export with the following properties:
现在,创建具有以下属性的默认导出:
export default {
Int: () => casual.integer(0),
Author: () => ({
firstName: casual.first_name,
posts: () => new MockList([1, 7])
}),
Post: () => ({
title: casual.title
})
}
The Int
declaration takes care of all integer types appearing in our schema and it will ensure that Post.votes
will be positive or zero.
Int
声明会处理出现在我们架构中的所有整数类型,并确保Post.votes
为正数或零。
Next, Author.firstName
will be a reasonable first name. MockList is used to ensure the number of posts associated with each Author will be between 1 and 7. Finally, casual will generate a lorem ipsum title
for each Post
.
接下来, Author.firstName
将是一个合理的名字。 MockList用于确保与每个Author相关的帖子数量在1到7之间。最后,Casual将为每个Post
生成一个lorem ipsum title
。
Now the generated output varies each time the query is executed. And it looks credible:
现在,每次执行查询时,生成的输出都会变化。 而且看起来很可信:
{
"data": {
"author": {
"firstName": "Eldon",
"posts": [
{
"title": "Voluptatum quae laudantium",
"votes": 581
},
{
"title": "Vero quos",
"votes": 85
},
{
"title": "Doloribus labore corrupti",
"votes": 771
},
{
"title": "Qui nulla qui",
"votes": 285
}
]
}
}
}
I just scratched the surface of what casual can do, but it is well-documented and there’s nothing much to add.
我只是简单介绍了随便可以做什么,但有据可查,没有什么可补充的。
Sometimes, though, there are values that have to conform to a standard format. I would like to introduce one more module: randexp.
但是,有时某些值必须符合标准格式。 我想再介绍一个模块: randexp 。
randexp allows you to generate values conforming to the regexp expression you provide it. For instance, ISBN numbers have the format:
randexp允许您生成符合您提供的regexp表达式的值。 例如,ISBN号具有以下格式:
/ISBN-\d-\d{3}-\d{5}-\d/
/ ISBN- \ d- \ d {3}-\ d {5}-\ d /
Now I can add Books to the schema, add books to Author, and generate ISBN and title for each Book
:
现在,我可以将Books添加到架构中,将book添加到Author中,并为每个Book
生成ISBN和书名:
// book.js
export default `
type Book {
ISBN: String
title: String
}
mocks.js:
mocks.js:
import casual from 'casual';
import RandExp from 'randexp';
import {
MockList
} from 'graphql-tools';
import {
startCase
} from 'lodash';
export default {
Int: () => casual.integer(0),
Author: () => ({
firstName: casual.first_name,
posts: () => new MockList([1, 7]),
books: () => new MockList([0, 5])
}),
Post: () => ({
title: casual.title
}),
Book: () => ({
ISBN: new RandExp(/ISBN-\d-\d{3}-\d{5}-\d/)
.gen(),
title: startCase(casual.title)
})
}
And here’s a new query:
这是一个新查询:
query PostsForAuthor {
author(id: 1) {
firstName
posts {
title
votes
}
books {
title
ISBN
}
}
}
Sample response:
样本回复:
{
"data": {
"author": {
"firstName": "Rosemarie",
"posts": [
{
"title": "Et ipsum quo",
"votes": 248
},
{
"title": "Deleniti nihil",
"votes": 789
},
{
"title": "Aut aut reprehenderit",
"votes": 220
},
{
"title": "Nesciunt debitis mollitia",
"votes": 181
}
],
"books": [
{
"title": "Consequatur Veniam Voluptas",
"ISBN": "ISBN-0-843-74186-9"
},
{
"title": "Totam Et Iusto",
"ISBN": "ISBN-6-532-70557-3"
},
{
"title": "Voluptatem Est Sunt",
"ISBN": "ISBN-2-323-13918-2"
}
]
}
}
}
So that’s the basics of mocking using graphql-tools plus a couple of other useful modules .
这就是使用graphql-tools以及其他几个有用模块进行模拟的基础。
Note: I use snippets throughout this post. If you want to follow along in a broader context, sample code is here.
注意 :在本文中,我都会使用摘要。 如果你想沿着更广的范围内遵循,示例代码是在这里 。
The Full source is on GitHub for your perusal.
完整的源代码在GitHub上供您阅读。
Give me a hand if you found this article informative.
如果您发现本文内容丰富,请给我帮助。
翻译自: https://www.freecodecamp.org/news/mocking-graphql-with-graphql-tools-42c2dd9d0364/
graphql tools