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.