首页 > 解决方案 > 使用 Test::Mojo 上传的文件为空

问题描述

我已经实现了一个 Mojolicious Web 服务作为一个模块,它通过 POST 接受文件上传。一个示例 cURL 命令:

curl -X POST http://localhost:3000/process -F inputFile=@file.txt

这按预期工作,处理文件并返回结果。

我现在正在尝试使用Test::Mojo来测试它,如下所示:

my $t = Test::Mojo->new( 'TK::Proxy' );

my $data = {
    inputFile => { filename => 't/file.txt' },
};

$t->post_ok('/process' => form => $data)
    ->status_is(200)

测试失败:

$ ./Build test
[...]
#   Failed test '200 OK'
#   at t/20_app.t line 44.
#          got: '400'
#     expected: '200'

调试代码显示上传的内容是空的。

我已经通过在测试之前添加一个简单的打印来验证它是否找到了该文件:

open FILE,'<', 't/file.pdf' or die("Could not read file");

while (my $line = <FILE>) {
    print STDERR ($line . "\n");
}

这会按预期输出文件。

因此,我的结论是错误出在post_ok调用和/或结构中$data,但我不知道在哪里。据我所知,调用看起来与文档中给出的示例完全相同。

这是在服务器端处理文件内容的方式:

my $self = shift()->openapi()->valid_input() or return;

my $input  = $self->validation()->output();

my $content;
eval {
    my $document = $input->{inputFile}->slurp;

    $content = $self->textractor()
        ->process(
            $input->{source},
            $input->{target},
            $document,
            _parse_runtime_params($input->{runtimeParams}),
        );
};

事实证明,$input->{inputFile}->slurp;测试的结果是一个空字符串。然而,在 cURL 调用中,它正确地包含了文件内容。

标签: perlmojoliciousmodule-build

解决方案


正如@Boroding 所指出的,解决方案确实是替换fileNamefile

my $data = {
  inputFile => { file => 't/file.txt' },
};
$t->post_ok('/process' => form => $data)->status_is(200);

据推测,文档示例中缺少此内容的原因是 test 不应依赖于外部文件。所以更简洁的方法是:

my $data = {
  inputFile => { content => "File content", fileName => 'file.txt' },
};
$t->post_ok('/process' => form => $data)->status_is(200);

推荐阅读