laravel created_at 时间戳_使用 HTTP 测试测试 Laravel 中间件

bb1b9060baf90157f22edfb9720cefe7.png
文章转发自专业的Laravel开发者社区,原始链接:https://learnku.com/laravel/t/34002

在本文中,我将展示一个使用 HTTP 测试中间件的实例。HTTP 级测试更能适应变化,可读性更强。

在最近与 Adam Wathan 和 Taylor Otwell 合拍的《全栈广播》(http://www.fullstackradio.com/72) 节目中,听到他们在 HTTP 测试中发现了许多实用价值,令人耳目一新。我发现 HTTP 测试更易编写和维护,但我确实觉得我在测试 Wrong™ ,或没有模拟(对象),隔离每一测试项在作弊一样。如果你还没有听过这一集的话,请听一听,里面充满了好的、实用的测试建议。

介绍

今年早些时候,我构建了一个中间件,用于在我的一个项目上验证和保护Mailgun webhook,并在Laravel News上的 用Mailgun对Laravel中的电子邮件进行入站处理 中对此进行了描述。 总之,我将演示如何在处理入站电子邮件时使用Laravel中间件验证Mailgun webhook(以确保webhook 实际上 来自Mailgun)。

在设置 Mailgun webhook 的核心部分时,作为 HTTP POST 有效负载部分的签名建议使用rquest提供的签名、时间戳和令牌来验证,从而保护您的 webhook。这是我发布的完整中间件:

<?phpnamespace AppHttpMiddleware;use Closure;
use IlluminateHttpResponse;class ValidateMailgunWebhook
{public function handle($request, Closure $next){if (!$request->isMethod('post')) {abort(Response::HTTP_FORBIDDEN, 'Only POST requests are allowed.');}if ($this->verify($request)) {return $next($request);}abort(Response::HTTP_FORBIDDEN, 'The webhook signature was invalid.');}protected function buildSignature($request){return hash_hmac('sha256',sprintf('%s%s', $request->input('timestamp'), $request->input('token')),config('services.mailgun.secret'));}protected function verify($request){if (abs(time() - $request->input('timestamp')) > 15) {return false;}return $this->buildSignature($request) === $request->input('signature');}
}

该中间件只接受 POST 请求,并将传入的签名与使用 Mailgun 密钥生成的签名进行比较。

我已经看到了各种测试中间件的方法,例如直接在单元测试中构建它,根据需要模拟对象,以及直接运行中间件。 在这篇文章中,我将向你展示如何使用更高级别的 HTTP 测试来测试此中间件。 你的整个堆栈将在测试中运行,让你更有信心 你的应用程序将会按预期工作。

将测试不直接绑定到特定的中间件实现 这是你能了解到的一个重要的福利。 我们可以完全重构中间件,而不需要更改任何测试或更新模拟来验证中间件是否正常工作。 我相信你会发现这些测试将会更加健壮。

配置

让我们使用示例Laravel 5.5项目快速构建对上述中间件的测试:

$ laravel new middleware-tests# 切换到 middleware-tests 文件夹
$ cd $_$ php artisan make:middleware ValidateMailgunWebhook

获取上面的中间件代码并将其粘贴到此中间件文件中。

接下来,将此中间件添加到 app/Http/Kernel.php 文件中:

protected $routeMiddleware = [// ...'mailgun.webhook' => AppHttpMiddlewareValidateMailgunWebhook::class,
];

编写HTTP测试

我们准备针对这个中间件编写一些测试,我们甚至不必定义任何路由routes/api.php来测试它!

首先,让我们创建功能测试文件:

$ php artisan make:test SecureMailgunWebhookTest

查看Mailgun中间件,以下是我们要测试的内容,以确保中间件按预期工作:

  1. 除了之外的任何HTTP动词 POST 都应该引起 403 Forbidden 响应。
  2. 无效的签名应该创建 403 Forbidden 响应。
  3. 有效签名应该通过并命中可调用的路由。
  4. 旧的时间戳应该引起 403 Forbidden 响应。

测试无效的HTTP方法

有了这个介绍,让我们编写第一个测试并设置我们的测试。

使用以下内容更新SecureMailgunWebhookTest文件:

<?phpnamespace TestsFeature;use TestsTestCase;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpKernelExceptionHttpException;class SecureMailgunWebhookTest extends TestCase
{protected function setUp(){parent::setUp();config()->set('services.mailgun.secret', 'secret');Route::middleware('mailgun.webhook')->any('/_test/webhook', function () {return 'OK';});}/** @test */public function it_forbids_non_post_methods(){$this->withoutExceptionHandling();$exceptionCount = 0;$httpVerbs = ['get', 'put', 'patch', 'delete'];foreach ($httpVerbs as $httpVerb) {try {$response = $this->$httpVerb('/_test/webhook');} catch (HttpException $e) {$exceptionCount++;$this->assertEquals(Response::HTTP_FORBIDDEN, $e->getStatusCode());$this->assertEquals('Only POST requests are allowed.', $e->getMessage());}}if (count($httpVerbs) === $exceptionCount) {return;}$this->fail('Expected a 403 forbidden');}
}

setUp() 方法中,我们定义一个假的 Mailgun 密钥,这样我们就可以针对这个密钥编写我们的测试,然后使用 any() 路由方法定义一个全局(catch-all)路由。 我们的路由将允许我们使用虚假的测试路由来使用中间件发出 HTTP 请求。

在 Laravel 5.5 中引入了 withoutExceptionHandling() 这个方法,这意味着我们可以在测试中自己来捕获抛出的异常,来替代使用 HTTP 响应来呈现这种异常。

try/catch 将会确保为每个 HTTP 请求捕获到 HttpException ,还会提供一个递增的异常计数器。如果捕获异常的数量与我们测试的 HTTP 请求的数量匹配,则测试通过。否则的话,如果我们的请求没有引起异常, $this->fail() 方法将会被调用。

与使用注释相比,我更喜欢捕获和断言异常的方法。它会让我感觉到更清楚,同时我还可以对异常进行断言,以确保异常是我所期望的。

您可以使用以下 PhpUnit 命令直接运行中间件特性测试::

# Run all tests in the file
$ ./vendor/bin/phpunit tests/Feature/SecureMailgunWebhookTest.php# Filter a specific method
$ ./vendor/bin/phpunit tests/Feature/SecureMailgunWebhookTest.php --filter=it_forbids_non_post_methods

Testing an Invalid Signature

下一个测试验证无效签名是否会导致 403 Forbidden error。这个测试与第一个测试不同,它使用的是 POST 方法,但发送无效的请求数据:

/** @test */
public function it_aborts_with_an_invalid_signature()
{$this->withoutExceptionHandling();try {$this->post('/_test/webhook', ['timestamp' => abs(time() - 100),'token' => 'invalid-token','signature' => 'invalid-signature',]);} catch (HttpException $e) {$this->assertEquals(Response::HTTP_FORBIDDEN, $e->getStatusCode());$this->assertEquals('The webhook signature was invalid.', $e->getMessage());return;}$this->fail('Expected the webhook signature to be invalid.');
}

我们传递将导致无效签名的假数据,然后断言在 HttpException中设置了正确的响应状态和消息。

测试有效签名

当 webhook 发送有效签名时,路由将处理响应,而不会中断中间件。中间件调用verify(),然后在签名匹配时调用$next()

if ($this->verify($request)) {return $next($request);
}

要编写此测试,我们需要发送有效的签名、时间戳和令牌。我们将在测试类中构建 SHA-256 hash 版本,它几乎是中间件内相同方法的副本。中间件和我们的测试都将使用在setup()方法中配置的services.mailgun.secret密钥:

/** @test */
public function it_passes_with_a_valid_signature()
{$this->withoutExceptionHandling();$timestamp = time();$token = 'token';$response = $this->post('/_test/webhook', ['timestamp' => $timestamp,'token' => $token,'signature' => $this->buildSignature($timestamp, $token),]);$this->assertEquals('OK', $response->getContent());
}protected function buildSignature($timestamp, $token)
{return hash_hmac('sha256',sprintf('%s%s', $timestamp, $token),config('services.mailgun.secret'));
}

我们的测试在中间件中使用相同代码构建签名,因此我们可以生成中间件期望的有效签名。 在测试结束时,我们断言在测试路径中返回的响应内容等于 "OK”。

使用旧时间戳测试失败

我们的中间件采取的另一个预防措施是,如果 timestamp 应用是旧的,则不允许请求继续进行。 测试类似于我们断言失败的其他测试,但是这次我们使一切有效(签名和令牌)除了 时间戳之外:

/** @test */
public function it_fails_with_an_old_timestamp()
{try {$this->withoutExceptionHandling();$timestamp = abs(time() - 16);$token = 'token';$response = $this->post('/_test/webhook', ['timestamp' => $timestamp,'token' => $token,'signature' => $this->buildSignature($timestamp, $token),]);} catch (HttpException $e) {$this->assertEquals(Response::HTTP_FORBIDDEN, $e->getStatusCode());$this->assertEquals('The webhook signature was invalid.', $e->getMessage());return;}$this->fail('The timestamp should have failed verification.');
}

密切关注 $timestamp = abs(time() - 16); 这将使中间件时间戳比较无效。

学习更多

这是一个在 HTTP 级别测试中间件的快速呈现。我更喜欢这种级别的测试,因为在中间件上使用 mocks (假数据)可能会很乏味,而且会绑定到特定的实现。如果我选择稍后重构,很可能需要重写我的测试以匹配新的中间件。通过 HTTP 测试,我可以自由地重构中间件,并期望得到相同的结果。

在 Laravel 中编写[HTTP 测试](https://laravel.com/docs/5.5/http-tests) 非常简便,我发现自己在这个级别上做了更多的测试。我相信我写的测试很容易理解,因为我们不 mock (模拟)任何东西。您应熟练使用Laravel 测试套件的断言(功能)来测试。这些工具使你的测试工作更容易,我敢说更有趣。

如果你不熟悉测试, 你也可以在 Laravel News中查看Test Driven Laravel 。我也经历过这个过程;如果您刚刚开始测试Web应用程序,那么这将是一个不错的资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动物识别专家系统python_Python有哪些作用?

Python是什么呢&#xff1f;Python是一种全栈的开发语言&#xff0c;如果能学好Python&#xff0c;前端、后端、测试、大数据分析、爬虫等这些工作你都能胜任。那Python有哪些作用呢&#xff1f;Python主要有以下四大主要应用&#xff1a;网络爬虫网站开发人工智能自动化运维接…

linux mint图标大小,Cinnamon:LinuxMint 15桌面设置小技巧

touchwiz自身也在做不断的革新&#xff0c;例如7屏分页&#xff0c;桌面切换3d效果&#xff0c;增强型的下拉菜单设置等。win10多桌面最多可以支持7个桌面开启&#xff0c;而且win10切换多桌面是有快捷键的&#xff0c;可以帮助用户迅速切换或创建以及关闭多桌面。切换方法一&a…

操作系统源代码_国产操作系统“之光”?Windows XP绝密源代码泄露,BT种子已在网上疯传...

微软的Windows操作系统是目前使用人数最多、覆盖最广的桌面操作系统&#xff0c;从安全角度来看&#xff0c;其系统源代码对于公众而言可以说是绝密。不过......现在......&#xff0c;黑客在4Chan平台上以BT种子文件的形式在线泄漏了多个旧Windows版本的源代码&#xff0c;包括…

linux设置多语言环境,怎么为Linux系统配置多语言环境?

这篇文章主要讲述了怎么为Linux系统配置多语言环境的基本方法&#xff0c;其中还包括编码的修改方法&#xff0c;我们就拿用户使用最多的Ubuntu和CentOS这两个为例子吧。需要的朋友可以参考下。修改 /etc/sysconfig/i18n 文件&#xff0c;如LANG“en_US.UTF-8”&#xff0c;xwi…

轴承新旧型号对照表_精密机床主轴轴承,高端轴承进口清关报关流程

精密机床的主轴对轴承精度的要求非常高&#xff0c;我国目前在这一技术上仍然处于一片空白&#xff0c;那么高精度的轴承要怎么进口呢&#xff1f;高精度轴承进口这块其他国家管控得比较严格&#xff0c;高精度轴承的进口又会遇到哪些问题呢&#xff1f;在我们的生活中轴承几乎…

开机自启动程序关闭方法_电脑非常卡,总有软件偷偷自启动?学会这1招,永久关闭它们!...

小编有一个朋友&#xff0c;前段子发微信问我&#xff0c;说他的电脑非常卡&#xff0c;重装电脑后&#xff0c;会好转许多&#xff0c;非常流畅&#xff0c;但是过了几天又卡了。我问了他的电脑配置&#xff0c;首先电脑的配置是绝对ok。当前一流水平&#xff0c;后来我远程操…

蒙特卡洛模拟_蒙特卡洛模拟法求期权价值

今年跟朋友讨论了一个期权问题。“Earn Out”方式并购下的金融工具确认。大致条款如下(非真实情况)&#xff1a;收购一家标的企业估值15000万元。盈利预测情况如下&#xff1a;收购协议中约定了第一期支付对价50%。同时第二期对价于2021年支付50%。同时若低于2021年净利润低于9…

双亲委派机制_面试官:双亲委派机制的原理和作用是什么?

说到双亲委派机制&#xff0c;就必须要先要弄清楚Java的类加载器什么是类加载器Java类加载器(ClassLoader)是Java运行时环境(JRE)的一部分&#xff0c;负责动态的将Java类加载到Java虚拟机的内存空间。类加载器有哪些主要有三个&#xff1a;引导类加载器(Bootstrap ClassLoader…

无广告的pdf阅读器_奥利给!免费无广告!功能超齐全!这样的良心国产软件,真的不多了!...

日常生活工作中&#xff0c;我们会碰到各种各样的PDF文档&#xff0c;它是一种全球通用的格式&#xff0c;由Adobe公司开发。PDF有通用性好、格式不会乱变、保真性高等优点。但同时&#xff0c;PDF也是让我们感到困惑最多的格式之一&#xff0c;因为与Word文档等其他常见办公软…

android自定义游戏闯关图,Android自定义View(四) -- Canvas

本文计划根据HenCoder系列文章进行学习&#xff0c;所以代码风格及博文素材可能会摘自其中。1 范围裁切范围裁切有两个方法&#xff1a; clipRect() 和 clipPath()。裁切方法之后的绘制代码&#xff0c;都会被限制在裁切范围内。1.1 clipRect()使用很简单&#xff0c;直接应用&…

iPhone记步和Android计步,手机中运动步数是如何计算的?

微信运动每天都记录着你走路的步数&#xff0c;他会形成榜单&#xff0c;走的多收到很多赞&#xff0c;走的少则无人关注&#xff0c;如果你走到第一&#xff0c;你的照片将霸占排行榜封面。所以一段时间&#xff0c;每个人为了霸占封面疯狂走路、刷步&#xff0c;然而有时我们…

智能机器人建房子后房价走势_明后年日照房价走势如何?究竟是“上涨”还是下降...

想要在偌大的城市中拥有一个属于自己的家&#xff0c;那就必须要先有自己的一套房子&#xff0c;因为房子和自己以后的幸福生活密切相关。但是面对着如今格外高昂的房价&#xff0c;让很多人对房子产生了一种遥不可及的感觉。那么明后年日照房价走势如何呢&#xff1f;究竟是会…

dota迷你盒子Android5,DOTA:第一批TI7的迷你Aegis复制品已经到货

原标题&#xff1a;DOTA&#xff1a;第一批TI7的迷你Aegis复制品已经到货各地华丽的工艺。节日期间&#xff0c;一些Dota 2粉丝的完美礼物被封顶&#xff0c;他们本周开始收到令人垂涎的“宙斯盾”(Aegis of Champions)的缩影复制品。今年5月4日至10月1日举行的国际7战斗通行证…

鸿蒙系统下拉菜单,鸿蒙的js开发部模式17:鸿蒙的系统能力的应用模块

1. 鸿蒙的系统能力主要涉及通知消息模块&#xff0c;在模拟器中也可以实践和获取初始界面&#xff1a;点击发送通知&#xff0c;顶部出现通知消息的图标下拉通知菜单栏&#xff0c;出现通知信息:js的业务逻辑代码&#xff1a;import notification from system.notification;no…

华为 原生android 6.0,安卓6.0原生桌面轻体验,我的手机从未如此流畅过

本帖最后由 啷个里格弄 于 2016-12-30 13:05 编辑1.png (188.33 KB, 下载次数: 65)2016-4-29 18:21 上传▏写在开头P8的EMUI系统或者称之为桌面在功能性和流畅度上都给我留下不错的印象。但是成天盯着一款桌面难免“七年之痒”&#xff0c;楼主这边就来给大家的P8换换口味&…

兼容ios和android的ar,安卓又落后 这几款AR游戏只能iOS玩

近日苹果正式推送iOS 11&#xff0c;很多AR应用也随之上线。iOS 11一个很重要的亮点就是AR增强现实&#xff0c;利用它用户可以实现很多前所未有的体验&#xff0c;比如将室内的环境与游戏融为一体&#xff1b;还能测量距离。想知道你喜欢的明星身高吗&#xff1f;打开Measure这…

dilink智能网联系统鸿蒙系统,【图】秦Pro DM DiLink智能网联系统实测解读_汽车江湖...

一辆天天接触的车对于车主而言&#xff0c;早已不是一辆车这么简单了&#xff0c;更多时候它还充当我们的“好伙伴”甚至是“知己”&#xff0c;多少人下班停好车以后不愿意下车&#xff1f;因为他们知道这是一个分界点&#xff1a;推开车门你就是柴米油盐、是父亲、是儿子、是…

卓越性能代码_装好win10后,应该这样设置,才能压榨出系统十足的性能

用了这么久win10系统&#xff0c;你知道在win10中有不同的性能模式吗&#xff1f;而使用不同的性能模式会消耗不同的电量&#xff0c;就会为系统提供不同的性能。为了拥有好的性能&#xff0c;我们一般会在电源选项中给系统设置为高性能模式&#xff0c;但你以为这就够了吗&…

主管护士需要考计算机和英语吗,2020主管护师改为机考,一定要注意这些问题!...

原标题&#xff1a;2020主管护师改为机考&#xff0c;一定要注意这些问题&#xff01;中国卫生人才网官方通知已确定&#xff0c;2020年护理学中级既主管护师考试形式-推行机考。那么&#xff0c;人机对话考试怎么考&#xff0c;有什么注意事项&#xff0c;为考生整理如下&…

html引用c 变量,在jsp页面中定义全局变量,供其他页面引用

一、在一个jsp中引用另一个jsp的方法有&#xff1a;1.使用 jsp include指令(常用)&#xff1a;file属性是必填的(绝对或相对路径)&#xff0c;但它不支持任何的表达式&#xff0c;也不允许通过&#xff1f;挂参方式来传递参数。注意&#xff1a;一般页面的top和bottom固定的时候…