非常类似于使用部分形状对typescript进行单元测试,但我无法理解为什么部分类型被视为与完整版本不兼容。
我有一个单元测试,如果AWS lambda事件中的body
无效,则检查lambda是否返回400。为了避免给我的同事制造噪音,我不想创建具有完整APIGatewayProxyEvent
所有属性的invalidEvent
。因此,使用部分
it("should return 400 when request event is invalid", async () => {
const invalidEvent: Partial<APIGatewayProxyEvent> = {
body: JSON.stringify({ foo: "bar" }),
};
const { statusCode } = await handler(invalidEvent);
expect(statusCode).toBe(400);
});
const{statusCode}=wait处理程序(invalidEvent)
行编译失败,原因是:
Argument of type 'Partial<APIGatewayProxyEvent>' is not assignable to parameter of type 'APIGatewayProxyEvent'.
Types of property 'body' are incompatible.
Type 'string | null | undefined' is not assignable to type 'string | null'.
Type 'undefined' is not assignable to type 'string | null'.ts(2345)
我理解
APIGatewayProxyEvent
body可以是string | null
(从类型上看),但是string | null | undefined
是从哪里来的?为什么我的正文
(字符串)不是APIGatewayProxyEvent的有效正文
如何使用TypeScript部分测试AWS Lambda?
我可以使用
作为
来做类型断言,但是我发现部分更显式。下面的代码工作,虽然:
const invalidEvent = { body: JSON.stringify({ foo: "bar" }) } as APIGatewayProxyEvent;
type TestingEventWithBody = Omit<Partial<APIGatewayProxyEvent>, "body"> & Pick<APIGatewayProxyEvent, "body">;
it("should return 400 when request event is invalid", async () => {
const invalidEvent: TestingEventWithBody = { body: JSON.stringify({ foo: "bar" }) };
const { statusCode } = await handler(invalidEvent);
expect(statusCode).toBe(400);
});
在以下情况下失败:
Argument of type 'TestingEventWithBody' is not assignable to parameter of type 'APIGatewayProxyEvent'.
Types of property 'headers' are incompatible.
Type 'APIGatewayProxyEventHeaders | undefined' is not assignable to type 'APIGatewayProxyEventHeaders'.
Type 'undefined' is not assignable to type 'APIGatewayProxyEventHeaders'.ts(2345)
这里的问题是,分部类型将所有对象属性转换为可选:
type MyObj = { myKey: string | null };
type MyPartialObj = Partial<MyObj>;
// MyPartialObj is: { myKey?: string | null | undefined }
在类型MyObj
中,myKey
类型为string | null
。当我们将其转换为MyPartialObj
时,myKey
类型成为可选的,因此可能是未定义的
。所以现在它的类型是string | null | undefined
您的APIGatewayProxyEvent
类型要求body
为string | null
,但是由于您将其设置为部分,因此您所说的body
也可能是未定义的
。是的,您已经定义了它,但是您从未进行过类型缩小以验证它确实是一个字符串。因此,TypeScript必须关闭的所有类型都是您指定的类型,这也是部分类型
更新:扩展@jornsharpe在评论中所说的内容。我以前的解决方案似乎不起作用,它只是将错误推送到APIGatewayProxyEvent
中的下一个属性。看看他们的答案。问题是您试图模拟数据的一部分,而该类型希望所有数据都存在。创建一个对象,使每个属性的值都最小,而不是试图伪造它,这可能是最简单的。您可以将用作
,但这首先破坏了使用类型系统的全部意义
前面的答案:一个解决方案可能是使所有值都是可选的,除了body
:
const invalidEvent: Omit<Partial<APIGatewayProxyEvent>, 'body'> & Pick<APIGatewayProxyEvent, 'body'> = {
body: JSON.stringify({ foo: "bar" }),
};
另外,避免像瘟疫一样使用
作为x
,除非你完全确定自己在做什么。
我无法理解为什么部分类型被视为与完整版本不兼容
从根本上说,这是不可避免的-您从要求body
属性为string | null
的内容开始,并创建了要求较弱的string | null | undefined
的内容。在本例中,您确实提供了正文
,但这并不重要,因为处理程序
仅通过部分代码查看
无效事件
在不拥有
处理程序
API的情况下,实际上只有三种选择,没有一种是理想的:
实际提供完整的APIGatewayProxyEvent
(有关此操作的快捷方式,请参见末尾)
使用部分代码通常只是选项2中的一个步骤,使用:
const thing: Partial<Thing> = { ... };
whatever(thing as Thing);
而不是:
const thing = { ... } as Thing;
whatever(thing);
如果您拥有
处理程序
的API,最好的方法是应用接口隔离原则,并具体说明它实际需要做什么工作。如果只是body
,例如:
type HandlerEvent = Pick<APIGatewayProxyEvent, "body">;
function handler(event: HandlerEvent) { ... }
完整的
APIGatewayProxyEvent
仍然是处理程序的有效参数,因为它确实有一个
主体
(而且它还有其他属性这一事实与此无关,它们无法通过HandlerEvent
访问)。这还可以作为内置文档,说明您从完整对象中实际消费了什么。
在您的测试中,您现在可以创建较小的对象:
it("should return 400 when request event is invalid", async () => {
const invalidEvent: HandlerEvent = { body: JSON.stringify({ foo: "bar" }) };
const { statusCode } = await handler(invalidEvent);
expect(statusCode).toBe(400);
});
作为奖励,如果稍后发现您需要访问
处理程序
中的更多事件属性,您可以更新类型:
type HandlerEvent = Pick<APIGatewayProxyEvent, "body" | "headers">;
你需要更新测试数据以考虑到这一点,你会在任何地方得到错误。这不会发生在
const无效事件={...}作为APIGatewayProxy事件;
,您必须通过查看哪些测试在运行时失败来跟踪更改。
我在选项1中看到的另一个快捷方式是将函数包装在部分周围,提供合理的默认值:
function createTestData(overrides: Partial<APIGatewayProxyEvent>): APIGatewayProxyEvent {
return {
body: null,
headers: {},
// etc.
...overrides,
};
}
it("should return 400 when request event is invalid", async () => {
const invalidEvent = createTestData({ body: JSON.stringify({ foo: "bar" }) });
const { statusCode } = await handler(invalidEvent);
expect(statusCode).toBe(400);
});
在这种情况下,应尽可能减少默认值(
null
,0
,”
,空对象和数组,…),避免任何依赖于它们的特殊行为。
问题内容: 设置:我有一个用TypeScript编写的Node项目(纯Node,没有浏览器位)。我可以使用模块中的TypeScript编译器()来编译代码。到目前为止,一切都很好。 但是,我想使用Mocha编写测试,这就是我遇到的麻烦。我尝试了,但是不断出现以下错误: 看起来命令行最终被传递给,这显然不好。 问题答案: 对于任何尝试过 typescript-require 并遇到问题的人,您都可以
问题内容: 我正在使用JavaScript测试运行程序“摩卡”。 我的测试失败了,因此我将使用进行调试。 但是运行测试时,没有输出(仅来自Mocha的测试结果)。看来Mocha已捕获并抑制了我的输出! 如何让Mocha显示输出?(对于失败的测试)? 编辑: 抱歉!- 在测试期间可以正常工作!我肯定一直期望它抑制输出,而且我没有正确检查自己的代码。感谢您的回应。所以…话虽如此…也许抑制通过测试的输出
本教程上接教程第4部分。 我们已经建立一个网页投票应用,现在我们将为它创建一些自动化测试。 自动化测试简介 什么是自动化测试? 测试是检查你的代码是否正常运行的简单程序。 测试可以划分为不同的级别。 一些测试可能专注于小细节(某一个模型的方法是否会返回预期的值?), 其他的测试可能会检查软件的整体运行是否正常(用户在对网站进行了一系列的操作后,是否返回了正确的结果?)。这些其实和你早前在教程 1中
问题内容: 我们有一个使用JQuery UI Sortable 的可排序列表,我们正在尝试使用Selenium自动进行排序。 看起来dragAndDrop函数应该可以工作,但是当我们调用它时,UI不会改变。但是,如果我们用Firebug来查看DOM,则会看到列表元素DID的顺序发生了变化。似乎只是UI无法刷新。 任何想法如何使其工作? 问题答案: 我们找不到可行的解决方案,因此我们只创建了辅助ja
我正在一个命令行NodeJS项目中使用TypeScript,处理代码问题。第2天,我从以下几点开始: 和摩卡咖啡单元测试: 当我运行主程序时,调试器会很好地命中TS源中的断点,但是当我尝试调试(失败的)单元测试时,断点不会被命中。我猜单元测试运行程序只是直接执行生成的. js文件,没有正确处理源映射。 有没有办法强迫VisualStudio让我正确调试一个全TS项目?
我试图弄清楚如何将Karma testrunner与Webpack和Typescript源文件一起使用。以该源文件作为唯一的测试文件为例: 测验规格ts 以及以下业力配置: 因果报应。配置。js 运行时未找到任何测试。浏览器将启动,但它表示找到0个测试。当我更改扩展名为并更新karma配置文件,因为它确实起作用,所以很明显是Typescript弄乱了它。 然而,当使用上面的配置手动运行webpac
我正在尝试测试我的上传我是usig Junit,Mockmvc和Spring 你能帮帮我吗? 错误堆栈跟踪: [org.springframework.test.context.support.dependencyinjectiontestexecutionlistener@361cb7a1]准备测试实例[endpoint.security.tests.uploadtest@6F7918F0]or
如何使用GoogleChrome的postman插件使用POST将FormData()对象发送到webapi。FormData()对象具有附加到其上的表单字段个人ID和MessageBody。我尝试过这样的东西,但没有用: