Home > Software design >  It is a good test? rspec
It is a good test? rspec

Time:12-17

I am new to unit tests and I am curious to improve myself. I have a task where I need to generate hashtag (a codewars kata).

It needs to return false if string is empty or has >= 140 characters. I am leaving the link, if necessary: https://www.codewars.com/kata/52449b062fb80683ec000024/train/ruby

def generateHashtag(str)
  arr = str.split.map(&:capitalize)
  arr.empty? || arr.join.length >= 140 ? false : '#'   arr.join
end

p generateHashtag(" Hello there thanks for trying my Kata") # "#HelloThereThanksForTryingMyKata"
p generateHashtag("    Hello     World   "                 ) # "#HelloWorld"
p generateHashtag(""                                       ) #  false
p generateHashtag('L' * 140) # false

The code works, but I am interested in writing rspec test correctly. Here what I wrote:

require 'rspec'
require './codewars/5kyu/hashtagGenerator'

describe 'generate hashtag when string length is less that 140' do
  before :each do
    generateHashtag(" Hello there thanks for trying my Kata").length < 140
  end

  describe 'adds # to the start' do
    it 'removes one space' do
      expect(generateHashtag(" Hello there thanks for trying my Kata"))
               .to eq("#HelloThereThanksForTryingMyKata")
    end

    it 'removes more than one space' do
      expect(generateHashtag("    Hello     World   ")).to eq("#HelloWorld")
    end
  end

  describe 'empty string' do
    it 'returns false' do
      expect(generateHashtag("")).to eq(false)
    end
  end
end

describe 'more than or equal to 140 characters' do
  it 'returns false' do
    expect(generateHashtag("L" * 140)).to be(false)
  end
end

Tests work. But I want to know your opinion: is it okay? Do I do right when using before to check if length of the string is < 140? Are there other ways to check length before each block? Sorry if question might sound dumb. I may be overengineering :(

CodePudding user response:

In general, your specs are great. You check two normal cases that have different whitespace patterns that seem to be important to you. And you check two edge cases – an empty input and an input that is too long.

But I see any benefit in checking that the output is shorter than 140 chars before each example. All your examples have hard coded inputs and hard-coded, expected outputs anyway, and therefore you already know that none of them will be longer than 149 chars.

Additionally, I would refactor the specs a bit, for example, but that is certainly opinionated:

require 'rspec'
require './codewars/5kyu/hashtagGenerator'

describe '#generate_hashtag' do
  subject(:hashtag) { generate_hashtag(input) }

  describe 'with valid input' do
    let(:input) { ' Hello there thanks for trying my Kata' }
    
    it 'returns the expected formatted output' do
      expect(hashtag).to eq('#HelloThereThanksForTryingMyKata')
    end
  end

  describe 'with input with an unusually amount of whitespace' do
    let(:input) { '    Hello     World   ' }
    
    it 'returns the expected formatted output' do
      expect(hashtag).to eq('#HelloWorld')
    end
  end

  describe 'with empty input' do
    let(:input) { '' }
    
    it 'returns false' do
      expect(hashtag).to be(false)
    end
  end

  describe 'with an input being longer than 139 chars' do
    let(:input) { "L" * 140) }
  
    it 'returns false' do
      expect(hashtag).to be(false)
    end
  end
end

Nitpicking: Ruby naming conventions for method names are that they should be written with underscores instead of camel case. Which means Ruby would prefer generate_hashtag over generateHashtag. Therefore, I already change the method naming in my above answer.

  •  Tags:  
  • ruby
  • Related