# Input / Output Tests

This is an example of how you can mock input values and test the output stream of student code.&#x20;

The student must use the `puts` function to prompt the user for their first name, then use `gets.chomp` to collect the first name without a newline attached, and again for their last name.  Then, print `Hello, firstname lastname!` including the person's first and last name.&#x20;

**Sample Run:**

```
What is your first name?
Jane
What is your last name?
Doe
Hello, Jane Doe!
```

It assumes the student's file name is `example.rb`.  Replace the `require` with whatever your student's file name is.&#x20;

*Note: This code converts the output to all lowercase and removes spaces to compare against the correct value.*

#### **Grading Tests:**

```ruby
require 'rspec'
require 'stringio'

student_code = File.read("/usercode/example.rb") 
new_student_code = student_code.gsub(" gets", " $stdin.gets") 
File.open("/usercode/example.rb", "w") do |f|
  f.write(new_student_code)
end

RSpec.describe "CodingRoomsUnitTests" do

    describe 'Giving code Jane and Doe as inputs' do
        it "output should equal 'Hello, Jane Doe!'" do
            input = StringIO.new()
            output = StringIO.new()
            input.puts "Jane"
            input.puts "Doe"
            input.rewind
            $stdin = input
            $stdout = output
            load '/usercode/example.rb'
            expect(output.string).to include("Hello, Jane Doe!")
            $stdin = STDIN
            $stdout = STDOUT
        end
    end

    describe 'Giving code Joe and Mazzone as inputs' do
        it "output should equal 'Hello, Joe Mazzone!'" do
            input = StringIO.new()
            output = StringIO.new()
            input.puts "Joe"
            input.puts "Mazzone"
            input.rewind
            $stdin = input
            $stdout = output
            load '/usercode/example.rb'
            expect(output.string).to include("Hello, Joe Mazzone!")
            $stdin = STDIN
            $stdout = STDOUT
        end
    end

end
```

RSpec, the unit testing framework we are using, seems to have a hard time replacing the standard input stream.  That is why you see this code at the beginning of our test file.

```ruby
student_code = File.read("/usercode/example.rb") 
new_student_code = student_code.gsub(" gets", " $stdin.gets") 
File.open("/usercode/example.rb", "w") do |f|
  f.write(new_student_code)
end
```

To allow RSpec to load a new standard input stream, we need to replace all instances of `gets` and use `$stdin.gets`. Instead of teaching students to not use `gets` and always use `$stdin.gets`, we can simply add the above code to replace all instances of `gets` with `$stdin.gets`.

***Note:** On Coding Rooms, the testing instance copies the student code so the above doesn't actually modify the student submission, it just changes it for the test.  Other platforms or your local may behave differently.*

#### Sample Solution:

{% code title="example.rb" %}

```ruby
puts 'What is your first name?'
firstname = gets.chomp

puts 'What is your last name?'
lastname = gets.chomp

puts 'Hello, ' + firstname + " " + lastname + "!"
```

{% endcode %}
