简体   繁体   中英

Rails test service object with MiniTest

I'm trying to understand MiniTest in Rails 6 to use it instead of RSpec. Practically all the materials I found concern two things: controller and model tests and they don't touch such an important thing as service objects. I've got below service object which simply updates three User fields - status, status_updated_at and failed_attempts. To simplify the example, I will omit the remaining conditions.

  class FailedAttributes
    def initialize(user)
      @user = user
    end

    def call
      transaction do
        user.class.update_counters(user.id, failed_attempts: 1)
        user.update(status: 'inactive', status_updated_at: DateTime.now)
      end
    end

RSpec test would be very simple but how to write it using MiniTest? I've got simple:

require 'test_helper'

class FailedAttributesTest < ActiveSupport::TestCase
  setup do
    @user = users(:registered)
  end
end

And how to pass @user variable to run the class and check if @user was updated?

Minitest is really just a very bare bones TDD setup with very few opinions on how to write your tests.

Minitest::Test does not have a built in equivilent to let/let! or the implicit subject in RSpec. Instead dependencies are quite often setup in the setup block:

require 'test_helper'

class FailedAttributesTest < ActiveSupport::TestCase
  # Arrange
  setup do
    @user = users(:registered)
    @service = FailedAttributes.new(@user)
  end

  def test_does_something
    # Act
    @service.call
    # Assert
    assert_equals(@user.reload.foo, 'bar')
  end
end

You can if you want create memoized helper methods somewhat like let in RSpec:

require 'test_helper'

class FailedAttributesTest < ActiveSupport::TestCase

  def test_does_something
    # Act
    service.call
    # Assert
    assert_equal(user.reload.foo, 'bar')
  end

  private

  def user
    @user ||= users(:registered)
  end

  def service
    @service ||= FailedAttributes.new(user) 
  end
end

As to how to test service objects - thats really a close to impossible subject to cover as service objects are really just a design pattern which consists of writing simple objects that perform a single job and take all needed input either as constructor or method arguments. Testing them is actually not that unlike testing any other type of object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM