问题描述
这有可能吗?
你好朋友.我正在使用AWS AppSync + DynamoDB构建应用程序,并且开始有大量解析器映射模板,所有模板均使用Apache Velocity模板语言(VTL)编写.
Hello friends.I'm in the process of building an application using AWS AppSync + DynamoDB and I'm starting to have quite a large pile of resolver mapping templates, all which are written using the Apache Velocity Template Language (VTL).
我开始担心的是这些vtl文件对应用程序非常重要(因为它们定义了如何检索数据),并且其中一个错误可能造成严重破坏.因此,就像系统的任何关键部分一样,我想为它们编写一些自动化的单元测试.但是我对其他这样做的人知之甚少.
The concern I'm starting to have is that these vtl files are quite critical to the application (since they define how data is retrieved) and a bug in one of the could wreak havoc. So like any critical part of a system... I would like to write some automated unit tests for them. But I haven't found much about others doing this.
- 如果您正在使用VTL(通过AppSync或API网关),如何测试它们?
- 是否有可能向速度模板编写自动化测试?
- 还是我走错了道路,我应该只使用Lambda作为我的解析器?
提前谢谢!
推荐答案
我花了一些时间自己弄清楚这一点,但是我找到了一种为VTL请求和响应模板编写单元测试的好方法.我使用了 amplify-appsync-simulator
npm包的VelocityTemplate类.到目前为止,我唯一需要注意的是,您需要在VTL中使用 $ context
,模拟器的VTL渲染器无法识别缩写的 $ ctx
.检查一下:
It took me a while to figure this out myself, but I found a good way to write unit tests for my VTL request and response templates. I used the amplify-appsync-simulator
npm package's VelocityTemplate class. The only caveat I have seen so far is that you need to use $context
in your VTL, the abbreviated $ctx
is not recognized by the simulators VTL renderer. Check it out:
我的VTL:
#set( $timeNow = $util.time.nowEpochMilliSeconds() )
{
"version" : "2018-05-29",
"operation" : "PutItem",
"key": {
"pk" : { "S" : "game#${util.autoId()}" },
"sk" : { "S" : "meta#${timeNow}" }
},
"attributeValues" : {
"players": { "L" : [
{ "M" : {
## num and color added at start game
"player": $util.dynamodb.toDynamoDBJson($context.args.input.player)
}}
]},
"createdBy": { "S": "${context.identity.sub}"},
"gsipk": { "S": "${context.args.input.status}"},
"gsisk": { "S": "${context.args.input.level}#${context.args.input.maxPlayers}"},
"gsipk2": {"S": "game"},
"turns": { "L": [] },
"nextPlayerNum": { "N": 1 },
"createdAt": { "N": ${timeNow} },
"updatedAt": { "N": ${timeNow} }
}
}
我的测试:
import { AmplifyAppSyncSimulator } from 'amplify-appsync-simulator'
import { VelocityTemplate } from "amplify-appsync-simulator/lib/velocity"
import { readFileSync } from 'fs'
import path from 'path';
const vtl = readFileSync(path.join(__dirname, '..', 'addGame-request-mapping-template.vtl'))
const template = {
content: vtl
}
const velocity = new VelocityTemplate(template, new AmplifyAppSyncSimulator)
describe('valid user and request', () => {
// This is the graphql input
const validContext = {
arguments: {
input: {
player: 'player#1234',
maxPlayers: 4,
status: 'new',
level: 7
}
},
source: {}
}
// This is a logged in user with a JWT
const requestContext = {
requestAuthorizationMode: 'OPENID_CONNECT',
jwt: {
sub: 'abcd1234'
}
}
const info = {
fieldNodes: []
}
it('works', () => {
const result = velocity.render(validContext, requestContext, info)
expect(result).toEqual({
result: {
version: "2018-05-29",
operation: "PutItem",
key: {
pk: { S: expect.stringMatching(/^game#[a-f0-9-]*$/) },
sk: { S: expect.stringMatching(/^meta#[0-9]*$/)}
},
attributeValues: {
players: {
L: [
{ M: { player: { S: validContext.arguments.input.player }}}
]
},
createdBy: { S: requestContext.jwt.sub },
gsipk: { S: validContext.arguments.input.status },
gsisk: { S: `${validContext.arguments.input.level}#${validContext.arguments.input.maxPlayers}`},
gsipk2: { S: 'game' },
turns: { L: [] },
nextPlayerNum: { N: 1 },
createdAt: { N: expect.any(Number) },
updatedAt: { N: expect.any(Number) }
}
},
stash: {},
errors: [],
isReturn: false
})
})
})
这篇关于如何编写速度模板的单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!