c++ 邮件服务器代码

几乎所有应用程序都有一个共同的要求,即它们需要向注册用户发送一封电子邮件,以通知某些事情。 它可能是发票,操作确认或密码恢复。 如何测试该用例可能具有挑战性,对于单元测试,可以使用模拟和存根,但是要进行测试整个堆栈的组件测试。

Docker和MailHog如何帮助您测试这部分代码。

MailHog是用于开发人员的电子邮件测试工具的超级简单的SMTP服务器:

配置您的应用程序以使用MailHog进行SMTP传递

在Web UI中查看消息,或使用JSON API检索消息

(可选)将邮件释放到真实的SMTP服务器以进行传递

安装了MailHog的Docker映像

请注意,由于您可以检索使用JSON API发送到邮件服务器的任何消息,因此,验证消息是否确实已传递以及在任何消息字段上都置为断言确实非常简单。

Arquillian Cube是Arquillian扩展,可用于在测试中管理Docker容器。 要使用它,您需要在计算机上运行的Docker守护程序(它可以是本地的,也可以不是本地的),但可能在本地。

Arquillian Cube提供了三种定义容器的不同方法:

  • 定义docker-compose文件。
  • 定义容器对象。
  • 使用容器对象DSL。

在此示例中,我将向您展示“容器对象DSL”方法,但其他方法也都可以。

ContainerDslRule (如果您使用的是JUnit规则),或使用Arquillian运行器 (如果使用的是JUnit,TestNG或Spock)。 您可以在http://arquillian.org/arquillian-cube/#_arquillian_cube_and_container_object_dsl上了解有关容器对象DSL的更多信息。

作为Redis容器定义的示例:

@ClassRule
public static ContainerDslRule redis = new ContainerDslRule("redis:3.2.6")
                                               .withPortBinding(6379);

Jedis jedis = new Jedis(redis.getIpAddress(), redis.getBindPort(6379));
jedis.set("foo", "bar");

运行此测试时,将启动Redis Docker映像,执行测试,最后停止Docker实例。

Mailhog Docker映像来实现Redis。

ContainerDslRule是一个泛型类,可以对其进行扩展以变得更具体于具体的用例。 这就是我们要做的 Mailhog

public class MailhogContainer extends ContainerDslRule {
    protected MailhogContainer(String image) {
        super(image);
    }

    public static MailhogContainer createDefaultMailhogContainer() {
        MailhogContainer mailhogContainer = new MailhogContainer("mailhog/mailhog:v1.0.0");
        mailhogContainer.withPortBinding(1025, 8025);
        return mailhogContainer;
    }

    public void should_receive_email_with_subject(String subject) {
        final ArrayList<String> expected = new ArrayList<>();
        expected.add(subject);

        RestAssured.given()
            .when()
            .get("http://" + this.getIpAddress() + ":" + this.getBindPort(8025) + "/api/v1/messages")
            .then()
            .assertThat()
            .body("Content.Headers.Subject", CoreMatchers.hasItems(expected));
    }

}

首先,我们需要创建一个从 ContainerDslRule ,因此所有内容仍然是JUnit规则,而是自定义规则。 然后我们创建一个工厂方法来创建 MailhogContainer对象,设置图像名称和绑定端口。 最后,使用一种断言方法来连接到Mailhog服务器的Rest API,以检查是否有给定主题的消息。

然后,我们可以使用此新规则编写测试。

public class MailServiceTest {

    @ClassRule
    public static MailhogContainer mailhog = MailhogContainer.createDefaultMailhogContainer();

    @Test
    public void should_send_an_email() throws Exception {

        // given
        final MailService mailService = new MailService(
            mailhog.getIpAddress(),
            mailhog.getBindPort(1025));

        // when
        mailService.send("lollypop", "lolly.pop@mymail.com", "Invoice: 1234",
            "Thank you very much for buying this product. Here's your invoice");

        // then
        mailhog.should_receive_email_with_subject("Invoice: 1234");
    }

}

Docker容器配置来配置MailService类,它发送一封电子邮件,最后将其委派给容器对象以验证是否已接收到该电子邮件。

请注意,将所有内容放入对象中会使该对象在其他测试甚至其他项目中可重复使用。 您可以使用所有自定义开发的容器对象创建一个独立的项目,然后重复使用它们,将其作为测试项目导入到托管项目中。

代码: https : //github.com/lordofthejars/mailtest

翻译自: https://www.javacodegeeks.com/2017/10/testing-code-requires-mail-server.html

c++ 邮件服务器代码