DEPENDENCY INJECTION IN TESTING

In this blog, we will be looking at dependency injection in testing using StringIO objects in Ruby Rspec to test user input and output.




Carrying out tests is a staple practice for any developer or engineer to create something that works as expected. Most engineers easily work with this to affirm that their program works and to grow it even further.


In Ruby specifically, you can use different gems for testing but in this case, we will be looking at Rspec. Most people developers use return values to run their tests and confirm that their program works and this is an already full proof way of doing so. So how would you test input and output in ruby how would it look like? Most of the people new to testing generally will do it in the following method. If they are using the TDD approach

Class Test_mule_input_output
	def test_method
		puts ‘put in your date of birth’
		date = gets.chomp
		date #to return the date
	end
end
RSpec.describe Test_mule_input_output do
	it ‘Test for user input’ do
	test_class = Test_mule_input_output.new
	expect(test_class.test_method).to eq(‘1993’)
	end
end

This approach works and can prove that what you want to do works but each time you run the test the terminal, CLI is used this suspends the program till output and input are printed on the CLI and the user returns their input.

This is ok if you are sure you will be taking input once or twice only throughout the method and if it is not a feature you have to heavily test with different values or different data types. Althoguh this is not deisrable generally as you have to have tests that are fast, are easy to debug and require minimal dev input. This is why having the test be suspended each time to run the programme makes it very tedious.


How else can we do this that we do not have to stall the program and do not have to use the CLI to make the test work? Well, this should be something you heavily consider in case you have a tonne of different input points or maybe you have a lot of data types or data points to try out on the input/output method. This should be where StringIO comes in, in ruby.

require ‘stringio’

Always remember to require and call stringio into the file where you want to use it in

require ‘stringio
Class Test_mule_input_output
	def initialize(output,input)
		@output = output
		@input = input
	end
	def test_method
		@input.puts ‘put in your date of birth’
		date_1 = @output.gets.chomp
		date_2 = @output.gets.chomp
		date_1,date_2 #to return the date
	end
end
RSpec.describe Test_mule_input_output do
	it ‘Test for user input’ do
        output = StringIO.new
	input = StringIO.new(‘1993\n1998\n’)
	test_class = Test_mule_input_output.new(output,input) 

	expect(test_class.test_method).to eq(‘1993’,’1998’)
	end
end

With the above code you can test a lot of user input and output without having the terminal slow down any of the work that you are doing. To avoid creating new buffers when creating new StringIO objects for input add the number of input into the arguments and each time that

we should rerun the same object it moves on to the next argument. You can also assign the data point to a new variable to keep each data point independently.


StringIO replaces all IO streams with the arguments added when creating the object within the data buffer temporariiy storing the expected output and input.This ends up being used during the test. However to use this the same code to display to the CLI stdout and stdin can be used. Since we called initilaised the values output and input we can call stdin and stdout as arguments while creating a new object for when we are about to run the code and need it to display values on the CLI. It will look something like this where you want to run it:


		test_class = Test_mule_input_output.new($stdout, $stdin)


These will replace the output, input values initilialised with the variables of the same name and will run whatever code you intended to use StringIO objects  on in the CLI


This way makes it a lot more easier and efficient to carry out any tests that you have without having to suspend your programme on CLI keeping your tests fast which is another essential feature of any good test. 



Previous
Previous

Inheritance vs Composition

Next
Next

Law of Demeter