Rails - 发送测试电子邮件和禁用数据库写入的框架

时间:2017-09-09 12:06:08

标签: ruby-on-rails email ruby-on-rails-5 mongoid6

我有一个包含多种类型客户的网站(例如管理员,经理,市场营销等)

使用Rails,我被要求向这些人发送测试电子邮件,以便他们可以在自己的电子邮件客户端上预览电子邮件+防火墙限制+查看电子邮件是否进入促销文件夹。我需要能够向每种用户类型发送一组特定的电子邮件(此类测试很少,但最终我们公司的任何管理员都应该能够使用前端界面发送测试电子邮件)。

我想要的是,为每个用户类型编写一个类,它会注册此用户可能在某个时刻收到的电子邮件,并在仅构建模式下使用(例如FactoryGirl)( no写入DB !!)构建使用deliver_now发送电子邮件所需的模型(因此我避免了序列化/反序列化问题)。我希望能够在我的真实生产环境中运行这个系统(以便我可以使用我的真实电子邮件信誉,签名等)。

是否有一种简单的方法可以禁用数据库写入(因此我确保所有示例模型在用于发送电子邮件后都会被销毁?)?一个简单的选择是使用只读数据库凭据启动服务器,但也许有一些安全可以避免太多麻烦。

以下是我的代码的样子

module Testing
  module Emails
    class UserTypeAdmin < Base
      attr_accessor, :new_user, :admin
      register_email :created_new_user, type: :user_management do
        UserManagementMailer.user_created(new_user, creator: admin)
      end

      def prepare_models
        self.admin = FactoryGirl.build(:admin)
        self.new_user = FactoryGirl.build(:user)
      end
    end
  end
end

module Testing
  module Emails
    class Base
      class < self
        # my logic to register emails, definitions of #register_email, etc.
      end

      def initialize(tester_emails, ccs = []) 
        @tester_emails = tester_emails
        @ccs = ccs
        prepare_models
      end

      def send_email(email_name)
        email = instance_eval(registered_emails(email_name))
        email.to = @tester_emails
        email.cc = @ccs
        email.deliver_now
      end

我的FactoryGirls工厂非常混乱,虽然我使用:build方法,但有些工厂是使用:create策略的关联编写的,所以只是为了确保,我想要锁定数据库写入所以我可以很容易地防止我的数据库上的坏噪音(我使用Mongoid所以我没有一个简单的事务机制来取消我的所有写入)

1 个答案:

答案 0 :(得分:0)

因此,一个非常简单的解决方案是编写一个规范,检查没有任何内容写入数据库。使用这个我能够调试一些模型被持久存在的情况。

require 'rails_helper'

describe Testing::Email::UserTypeAdmin do
  let(:tos) { ['admin@example.com'] }
  let(:ccs) { ['adminmjg@example.com'] }
  let(:tested_models) {[
    User, Admin, 
    Conversation, Message, # etc.
  ]}

  subject do
    described_class.new(tos, ccs)
  end

  context 'testing all emails' do
    it 'does nothing with the DB' do
      subject.send_all_emails
      aggregate_failures 'no persistence' do
        tested_models.each do |model|
          expect(model.count).to eq(0), "#{model.name} was persisted"
        end
      end
    end
  end
end

我仍然在寻找更好的解决方案: - )