Refactor - example 2

Look at the two tests you have for this feature. They are hard to read. The relevant information for the tests is kind of unstructured. We are going to clean it up.

Replace the two tests with the following code:

func test_MakeHeadline_ReturnsStringWithEachWordStartCapital() { 
  let input           = "this is A test headline" 
  let expectedOutput  = "This Is A Test Headline" 
   

  let headline = viewController.makeHeadline(from: input) 
   

  XCTAssertEqual(headline, expectedOutput) 
} 
 
func test_MakeHeadline_ReturnsStringWithEachWordStartCapital2() { 
  let input           = "Here is another Example" 
  let expectedOutput  = "Here Is Another Example" 
   

  let headline = viewController.makeHeadline(from: input) 
   

  XCTAssertEqual(headline, expectedOutput) 
} 

Now, the tests are easy to read and understand. They follow a logical structure: precondition, invocation, and assertion.

Run the tests. All the tests should still pass. But how do we know whether the tests still test the same thing as they did earlier? In most cases, the changes we'll make while refactoring the tests don't need to be tested themselves. But, sometimes (such as in this case), it is good to make sure that the tests still work. This means that we need a failing test again. Go to makeHeadline(from:) and comment out (by adding // at the beginning) the line:

headline.remove(at: headline.index(before: headline.endIndex)) 

Run the tests again. Eureka! Both tests fail.

As you can see here, a failing test does not stop the tests in general. But you can change this behavior by setting continueAfterFailure to false in setUp().

Remove the comment symbols again to make the test pass again. Now, we need to refactor the implementation code. The implementation we have right now looks like it was translated from Objective-C to Swift (if you haven't used Objective-C yet, you have to trust me on this). But Swift is different and has many concepts that make it possible to write less code that is easier to read. Let's make the implementation more swiftly. Replace makeHeadline(from:) with the following code:

func makeHeadline(from string: String) -> String { 
  let words = string.components(separatedBy: " ") 
   

  let headlineWords = words.map { (word) -> String in 
    var mutableWord = word 
    let first = mutableWord.remove(at: mutableWord.startIndex) 

    return String(first).uppercased() + mutableWord 
    } 
   

  return headlineWords.joined(separator: " ") 
} 

In this implementation, we use the map function to iterate the words array and return another array containing the same words, but starting with uppercase letters. The result is then transformed into a string by joining the words using a space as the separator.

Run the tests again to make sure we didn't break anything with the refactoring. All the tests should still pass.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.115.21