Search code examples
rubyrefactoringminitestreusabilitycode-reuse

How can I split test methods for reuse in multiple case with Minitest?


I blocked for refactor my code in my Minitest files.

I have this example:

test_calls.rb

describe Aircall::Calls do
 before do
  @call_by_id = DefaultAircall::AIRCALL.calls.get_by_id(34043501)
  @call_by_user_id = DefaultAircall::AIRCALL.calls.get_by_user_id(80603)
 end

 describe "By id" do
  it "is Hash" do
    @call_by_id.must_be_instance_of Hash
  end

  it "no error return" do
    @call_by_id['error'].must_be_nil
  end
 end

 describe "by user id" do
  it "is Hash" do
    @call_by_user_id.must_be_instance_of Hash
  end

  it "no error return" do
    @call_by_user_id['error'].must_be_nil
  end
 end
end

test_users.rb

describe Aircall::Users do
describe "By id" do

  before do
    @user_by_id = DefaultAircall::AIRCALL.users.get_by_id(80603)
  end

  it "is Hash" do
    @user_by_id.must_be_instance_of Hash
  end

  it "no error return" do
    @user_by_id['error'].must_be_nil
  end

 end
end

Ideally, I want split my code in another file, like this:

class DefaultTest
 def initialize(element_to_test)
  @element_to_test = element_to_test
 end

 def defaults_tests
  describe "default" do
   it "is Hash" do
    @element_to_test.must_be_instance_of Hash
   end

   it "no error return" do
    @element_to_test['error'].must_be_nil
   end
  end
 end
end

So, I could be import my default tests in my different tests files.

I don't know if it's possible and how. I have succeeded one time I think, but the test don't appear in console. If I call a class method who run some Minitest tests, my task (who run the test) not accounting my default tests.


Solution

  • Great idea Keith Bennett ! Lambda is a good approach.

    I have my solution now:

    My module with lambda who run default tests: default_tests.rb

    module DefaultTest
    
     Run = ->(*variables_to_test) do
      describe "Default test" do
       variables_to_test.each do |variable|
    
        it "is Hash" do
          self.class.send(variable).must_be_instance_of Hash
        end
    
        it "no error return" do
          self.class.send(variable)['error'].must_be_nil
        end
    
       end
      end
     end
    
    end
    

    test_contacts.rb

    module TestAircall
     describe Aircall::Contacts do
    
      def self.contact_by_id
       @contact_by_id ||= DefaultAircall::AIRCALL.contacts.get_by_id(ENV['TEST_DEFAULT_CONTACT_ID'])
      end
    
      def self.contact_by_phone_number
       @contact_by_phone_number ||= DefaultAircall::AIRCALL.contacts.get_by_phone_number(ENV['TEST_DEFAULT_PHONE_NUMBER'])
      end
    
      def self.contact_by_email
       @contact_by_email ||= DefaultAircall::AIRCALL.contacts.get_by_email(ENV['TEST_DEFAULT_EMAIL'])
      end
    
      DefaultTest::Run.('contact_by_id', 'contact_by_phone_number', 'contact_by_email')
     end
    end
    

    test_users.rb

    module TestAircall
     describe Aircall::Users do
      def self.user_by_id
       @user_by_id ||= DefaultAircall::AIRCALL.users.get_by_id(ENV['TEST_DEFAULT_USER_ID'])
      end
    
      DefaultTest::Run.('user_by_id')
     end
    end
    

    I can call and run my default tests in every file test for any variable.