rpkamp / mailhog-behat-extension
Behat 的 Mailhog 扩展
Requires
- php: ^8.1
- behat/behat: ^3.8.0
- psr-discovery/http-client-implementations: ^1.0
- psr-discovery/http-factory-implementations: ^1.0
- rpkamp/mailhog-client: ^2.0
- symfony/dependency-injection: ^6.4 || ^7.0
- symfony/http-client: ^6.0
Requires (Dev)
- doctrine/coding-standard: ^8.0
- egulias/email-validator: ^2.1.23
- guzzlehttp/psr7: ^1.6
- mockery/mockery: ^1.3.3
- nyholm/psr7: ^1.3
- php-parallel-lint/php-parallel-lint: ^1.2
- phpmd/phpmd: ^2.9.1
- phpstan/phpstan: ^1.1
- phpstan/phpstan-mockery: ^1.1
- phpunit/phpunit: ^9.0
- swiftmailer/swiftmailer: ^6.2
README
A simple PHP (8.1+) Behat extension for Mailhog.
安装
This package does not require any specific HTTP client implementation, but it requires rpkamp/mailhog-client, which is based on HTTPlug, so you can inject your own HTTP client of choice. So you when you install this extension make sure you either already have an HTTP client installed, or install one at the same time as installing this extension, otherwise installation will fail.
composer require rpkamp/mailhog-behat-extension <your-http-client-of-choice>
For more information please refer to the HTTPlug documentation for Library Users.
用法
在 Behat 中注册扩展
将扩展添加到您的 behat.yml
如下所示
default: suites: # your suite configuration here extensions: rpkamp\Behat\MailhogExtension: base_url: http://localhost:8025 purge_tag: email # optional, defaults to 'email'
The base_url
is the URL where the Mailhog Web UI is listening to (by default this is http://localhost:8025). The
purge_tag` is the behat tag that triggers a purge in mailhog before the scenario/feature (see "Use email tag to purge emails before scenarios")
使用 MailhogContext
The easiest way to get started is to configure behat to use rpkamp\Behat\MailhogExtension\Context\MailhogContext
like so
default: suites: contexts: - rpkamp\Behat\MailhogExtension\Context\MailhogContext
This enables the following Gherkin for your scenarios to make assumptions on received email messages
Given my inbox is empty Then I should see an email with subject "subject" Then I should see an email with body "body" Then I should see an email from "sender@domain.example" Then I should see an email with subject "subject" and body "body" Then I should see an email with subject "subject" and body "body" from "sender@domain.example" Then I should see an email with subject "subject" from "sender@domain.example" Then I should see an email to "recipient@domain.example" Then I should see an email with subject "subject" to "recipient@domain.example" Then I should see an email with body "body" to "recipient@domain.example" Then I should see an email from "sender@domain.example" to "recipient@domain.example" Then I should see an email with subject "subject" and body "body" to "recipient@domain.example" Then I should see an email with subject "subject" and body "body" from "sender@domain.example" to "recipient@domain.example" Then I should see an email with subject "subject" from "sender@domain.example" to "recipient@domain.example" Then I should see "some text" in email Then there should be 2 emails in my inbox Then I should see an email with attachment "lorem-ipsum.pdf"
-
Given my inbox is empty
will actually purge all emails from Mailhog. -
The
2
inThen there should be 2 emails in my inbox
is variable, and the 's' in 'emails' is optional, so 'Then there is 1 email in my inbox' also works.
Alternatively you can "open" an email an run assumptions on the opened email
When I open the latest email from "sender@domain.example" When I open the latest email to "recipient@domain.example" When I open the latest email with subject "Hello world" When I open the latest email from "sender@domain.example" with subject "Hello world" When I open the latest email to "recipient@domain.example" with subject "Hello world" When I open the latest email with body "body" When I open the latest email with subject "subject" and body "body" When I open the latest email from "sender@domain.example" to "recipient@domain.example" When I open the latest email from "sender@domain.example" with body "body" When I open the latest email to "recipient@domain.example" with body "body" When I open the latest email from "sender@domain.example" with subject "subject" and body "body" When I open the latest email to "recipient@domain.example" with subject "subject" and body "body" When I open the latest email from "sender@domain.example" to "recipient@domain.example" with subject "subject" and body "body" Then I should see "Hello world" in the opened email Then I should see an attachment with filename "lorem-ipsum.pdf" in the opened email
Take care that the implementation of this currently isn't very efficient. If there are a lot of emails in Mailhog it might take a while, especially when the email you're looking for is not there.
实现 MailhogAwareContext
If you want to implement something more advanced than rpkamp\Behat\MailhogExtension\Context\MailhogContext
offers you can also implement rpkamp\Behat\MailhogExtension\Context\MailhogAwareContext
in your own context and implement the method in that interface
<?php declare(strict_types=1); use rpkamp\Mailhog\MailhogClient; use rpkamp\Behat\MailhogExtension\Context\MailhogAwareContext; class FeatureContext implements MailhogAwareContext { private $mailhog; public function setMailhog(MailhogClient $client) { $this->mailhog = $client; } }
Now every time your FeatureContext is initialized Behat will inject an rpkamp\MailhogClient
in it you can use using the $mailhog
property of your context. For example
<?php declare(strict_types=1); use rpkamp\Behat\MailhogExtension\Context\MailhogAwareContext; class FeatureContext implements MailhogAwareContext { // implement setMailhog as above /** * @Then /^there should be (\d+) email(?:s) in my inbox$/ */ public function thereShouldBeEmailInMyInbox(int $numEmails) { if ($numEmails !== $this->mailhog->getNumberOfMessages()) { throw new Exception('Unexpected number of messages.'); } } }
使用 email 标签在场景之前清除邮件(高级)
In scenarios where you want to make sure you have received the correct number of messages you will want to purge mailhog before the scenario is started. In order to do that add the @email
tag to either the scenario or the feature. As usual, when you apply it to the feature it applies to all scenarios within that feature.
Feature: @email Scenario: I should receive no more than 1 email Given some state When something happened Then there should be 1 email in my inbox
If you want to use a different tag you can supply the name (without the initial @) in the purge_tag
setting of this extension.
实现 OpenedEmailStorageAwareContext (高级)
If you want to write an extension/context for behat that uses the feature of opening email from this extension you can have your Context
implement OpenedEmailStorageAwareContext
<?php use rpkamp\Behat\MailhogExtension\Context\OpenedEmailStorageAwareContext; use rpkamp\Behat\MailhogExtension\Service\OpenedEmailStorage; class FeatureContext implements OpenedEmailStorageAwareContext { /** * @var OpenedEmailStorage */ private $storage; public function setOpenedEmailStorage(OpenedEmailStorage $storage) { $this->openedEmailStorage = $storage; } /** * @Then ^I do something with the opened email$ */ public function iDoSomethingWithTheOpenedEmail(): void { if (!$this->storage->hasOpenedEmail()) { throw new RuntimeException('No email opened, unable to do something!'); } /** @var \rpkamp\Mailhog\Message\Message $openedEmail */ $openedEmail = $this->storage->getOpenedEmail(); // do stuff with $openedEmail } }
运行测试
确保 Mailhog 已运行并运行
make test
为测试运行 Mailhog
您可以运行自己的Mailhog实例,或者使用提供的docker-compose文件来运行一个实例。要使用Docker运行Mailhog,请确保已安装Docker和docker-compose,然后运行
docker-compose up -d
Mailhog测试端口
为了防止测试期间与其他Mailhog实例发生端口冲突,测试时请期待Mailhog监听SMTP端口3025(而不是默认的1025),以及监听HTTP流量端口10025(而不是默认的8025)。