test_helper.rb 7.0 KB
Newer Older
C
Cristian Bica 已提交
1 2
require 'active_support/core_ext/hash/keys'

A
Abdelkader Boudih 已提交
3 4 5
module ActiveJob
  # Provides helper methods for testing Active Job
  module TestHelper
A
Abdelkader Boudih 已提交
6
    extend ActiveSupport::Concern
A
Abdelkader Boudih 已提交
7

A
Abdelkader Boudih 已提交
8
    included do
9 10 11 12 13 14 15 16 17 18 19 20
      def before_setup
        @old_queue_adapter  = queue_adapter
        ActiveJob::Base.queue_adapter = :test
        clear_enqueued_jobs
        clear_performed_jobs
        super
      end

      def after_teardown
        super
        ActiveJob::Base.queue_adapter = @old_queue_adapter
      end
A
Abdelkader Boudih 已提交
21

A
Abdelkader Boudih 已提交
22 23 24 25
      # Asserts that the number of enqueued jobs matches the given number.
      #
      #   def test_jobs
      #     assert_enqueued_jobs 0
A
Abdelkader Boudih 已提交
26
      #     HelloJob.perform_later('david')
A
Abdelkader Boudih 已提交
27
      #     assert_enqueued_jobs 1
A
Abdelkader Boudih 已提交
28
      #     HelloJob.perform_later('abdelkader')
A
Abdelkader Boudih 已提交
29 30 31 32 33 34 35 36
      #     assert_enqueued_jobs 2
      #   end
      #
      # If a block is passed, that block should cause the specified number of
      # jobs to be enqueued.
      #
      #   def test_jobs_again
      #     assert_enqueued_jobs 1 do
A
Abdelkader Boudih 已提交
37
      #       HelloJob.perform_later('cristian')
A
Abdelkader Boudih 已提交
38 39 40
      #     end
      #
      #     assert_enqueued_jobs 2 do
A
Abdelkader Boudih 已提交
41 42
      #       HelloJob.perform_later('aaron')
      #       HelloJob.perform_later('rafael')
A
Abdelkader Boudih 已提交
43 44 45 46 47 48 49 50 51 52
      #     end
      #   end
      def assert_enqueued_jobs(number)
        if block_given?
          original_count = enqueued_jobs.size
          yield
          new_count = enqueued_jobs.size
          assert_equal original_count + number, new_count,
                       "#{number} jobs expected, but #{new_count - original_count} were enqueued"
        else
53 54
          enqueued_jobs_size = enqueued_jobs.size
          assert_equal number, enqueued_jobs_size, "#{number} jobs expected, but #{enqueued_jobs_size} were enqueued"
A
Abdelkader Boudih 已提交
55
        end
A
Abdelkader Boudih 已提交
56 57
      end

58
      # Asserts that no jobs have been enqueued.
A
Abdelkader Boudih 已提交
59 60 61
      #
      #   def test_jobs
      #     assert_no_enqueued_jobs
A
Abdelkader Boudih 已提交
62
      #     HelloJob.perform_later('jeremy')
A
Abdelkader Boudih 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75
      #     assert_enqueued_jobs 1
      #   end
      #
      # If a block is passed, that block should not cause any job to be enqueued.
      #
      #   def test_jobs_again
      #     assert_no_enqueued_jobs do
      #       # No job should be enqueued from this block
      #     end
      #   end
      #
      # Note: This assertion is simply a shortcut for:
      #
76
      #   assert_enqueued_jobs 0, &block
A
Abdelkader Boudih 已提交
77 78 79
      def assert_no_enqueued_jobs(&block)
        assert_enqueued_jobs 0, &block
      end
A
Abdelkader Boudih 已提交
80

A
Abdelkader Boudih 已提交
81
      # Asserts that the number of performed jobs matches the given number.
82 83
      # If no block is passed, <tt>perform_enqueued_jobs</tt>
      # must be called around the job call.
A
Abdelkader Boudih 已提交
84 85 86
      #
      #   def test_jobs
      #     assert_performed_jobs 0
87 88 89 90
      #
      #     perform_enqueued_jobs do
      #       HelloJob.perform_later('xavier')
      #     end
A
Abdelkader Boudih 已提交
91
      #     assert_performed_jobs 1
92 93 94 95 96
      #
      #     perform_enqueued_jobs do
      #       HelloJob.perform_later('yves')
      #       assert_performed_jobs 2
      #     end
A
Abdelkader Boudih 已提交
97 98 99 100 101 102 103
      #   end
      #
      # If a block is passed, that block should cause the specified number of
      # jobs to be performed.
      #
      #   def test_jobs_again
      #     assert_performed_jobs 1 do
A
Abdelkader Boudih 已提交
104
      #       HelloJob.perform_later('robin')
A
Abdelkader Boudih 已提交
105 106 107
      #     end
      #
      #     assert_performed_jobs 2 do
A
Abdelkader Boudih 已提交
108 109
      #       HelloJob.perform_later('carlos')
      #       HelloJob.perform_later('sean')
A
Abdelkader Boudih 已提交
110 111 112 113 114
      #     end
      #   end
      def assert_performed_jobs(number)
        if block_given?
          original_count = performed_jobs.size
115
          perform_enqueued_jobs { yield }
A
Abdelkader Boudih 已提交
116 117 118 119
          new_count = performed_jobs.size
          assert_equal original_count + number, new_count,
                       "#{number} jobs expected, but #{new_count - original_count} were performed"
        else
120 121
          performed_jobs_size = performed_jobs.size
          assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
A
Abdelkader Boudih 已提交
122
        end
A
Abdelkader Boudih 已提交
123 124
      end

A
Abdelkader Boudih 已提交
125 126 127 128
      # Asserts that no jobs have been performed.
      #
      #   def test_jobs
      #     assert_no_performed_jobs
129 130 131 132 133
      #
      #     perform_enqueued_jobs do
      #       HelloJob.perform_later('matthew')
      #       assert_performed_jobs 1
      #     end
A
Abdelkader Boudih 已提交
134 135 136 137 138 139 140 141 142 143 144 145
      #   end
      #
      # If a block is passed, that block should not cause any job to be performed.
      #
      #   def test_jobs_again
      #     assert_no_performed_jobs do
      #       # No job should be performed from this block
      #     end
      #   end
      #
      # Note: This assertion is simply a shortcut for:
      #
146
      #   assert_performed_jobs 0, &block
A
Abdelkader Boudih 已提交
147 148
      def assert_no_performed_jobs(&block)
        assert_performed_jobs 0, &block
A
Abdelkader Boudih 已提交
149 150
      end

A
Abdelkader Boudih 已提交
151 152
      # Asserts that the job passed in the block has been enqueued with the given arguments.
      #
153
      #   def test_assert_enqueued_with
A
Abdelkader Boudih 已提交
154
      #     assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do
A
Abdelkader Boudih 已提交
155
      #       MyJob.perform_later(1,2,3)
A
Abdelkader Boudih 已提交
156 157 158 159 160 161 162 163 164 165
      #     end
      #   end
      def assert_enqueued_with(args = {}, &_block)
        original_enqueued_jobs = enqueued_jobs.dup
        clear_enqueued_jobs
        args.assert_valid_keys(:job, :args, :at, :queue)
        yield
        matching_job = enqueued_jobs.any? do |job|
          args.all? { |key, value| value == job[key] }
        end
166
        assert matching_job, "No enqueued job found with #{args}"
A
Abdelkader Boudih 已提交
167 168
      ensure
        queue_adapter.enqueued_jobs = original_enqueued_jobs + enqueued_jobs
A
Abdelkader Boudih 已提交
169 170
      end

A
Abdelkader Boudih 已提交
171 172 173 174
      # Asserts that the job passed in the block has been performed with the given arguments.
      #
      #   def test_assert_performed_with
      #     assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do
A
Abdelkader Boudih 已提交
175
      #       MyJob.perform_later(1,2,3)
A
Abdelkader Boudih 已提交
176 177 178 179 180 181
      #     end
      #   end
      def assert_performed_with(args = {}, &_block)
        original_performed_jobs = performed_jobs.dup
        clear_performed_jobs
        args.assert_valid_keys(:job, :args, :at, :queue)
182
        perform_enqueued_jobs { yield }
A
Abdelkader Boudih 已提交
183 184 185 186 187 188 189 190
        matching_job = performed_jobs.any? do |job|
          args.all? { |key, value| value == job[key] }
        end
        assert matching_job, "No performed job found with #{args}"
      ensure
        queue_adapter.performed_jobs = original_performed_jobs + performed_jobs
      end

191 192 193 194 195 196 197 198 199 200 201
      def perform_enqueued_jobs
        @old_perform_enqueued_jobs = queue_adapter.perform_enqueued_jobs
        @old_perform_enqueued_at_jobs = queue_adapter.perform_enqueued_at_jobs
        queue_adapter.perform_enqueued_jobs = true
        queue_adapter.perform_enqueued_at_jobs = true
        yield
      ensure
        queue_adapter.perform_enqueued_jobs = @old_perform_enqueued_jobs
        queue_adapter.perform_enqueued_at_jobs = @old_perform_enqueued_at_jobs
      end

A
Abdelkader Boudih 已提交
202 203
      def queue_adapter
        ActiveJob::Base.queue_adapter
A
Abdelkader Boudih 已提交
204
      end
A
Abdelkader Boudih 已提交
205 206 207 208 209 210 211 212 213 214 215 216 217 218

      delegate :enqueued_jobs, :enqueued_jobs=,
               :performed_jobs, :performed_jobs=,
               to: :queue_adapter

      private
        def clear_enqueued_jobs
          enqueued_jobs.clear
        end

        def clear_performed_jobs
          performed_jobs.clear
        end
    end
A
Abdelkader Boudih 已提交
219 220
  end
end