Skip to content

Characterization Testing: Hand

Do This First...

Be sure to have completed the prior labs before starting. You can also use the solution from the repository on GitHub and do a checkout of the tag lab2-start.

git checkout lab2-start

Goal

We'll continue characterizing and refactoring the display methods in the Hand class.

We're Done When...

We know we're done when we have removed all System.out.print statements from the Hand class, as well as any "display" methods that return a String.

A. Refactor Hand's Display Face Up Card

First, let's tackle the displayFaceUpCard method.

  1. As you did in the previous lab, create a characterization test for Hand.displayFaceUpCard() in a new test class (named HandDisplayTest). You can copy and paste this test to start:

    Start With...

    package com.r2ha.blackjack;
    
    import org.junit.jupiter.api.Test;
    
    import java.util.List;
    
    import static org.assertj.core.api.Assertions.assertThat;
    
    public class HandDisplayTest {
    
        @Test
        void displayFaceUpCardReturnsAsCorrectString() throws Exception {
            List<Card> cards = List.of(
                    new Card(Suit.HEARTS, Rank.ACE),
                    new Card(Suit.CLUBS, Rank.JACK));
            Hand hand = new Hand(cards);
    
            assertThat(hand.displayFaceUpCard())
                .isEqualTo("");
        }
    
    }
    
  2. For the refactor, the transformer class that we'll create (ConsoleHand) will need to access the Face Up card so:

    • Create a public dealerFaceUpCard() query method on Hand that returns the first Card from the list.

      Want to learn to use Extract Method here? Click >

      You can do this via an Extract Method refactoring of the existing displayFaceUpCard method:

      1. Select cards.get(0) only
      2. Do Refactor > Extract/Introduce > Method... or use the shortcut keys Cmd Option M (Mac) or Ctrl Alt M (Windows/Linux).
      3. Name the new method dealerFaceUpCard()
      4. Ensure that the method has public access visibility
  3. Refactor displayFaceUpCard to be a static method using Refactor > Make Static.... You will be presented with a parameter to pass in, which should be hand. Choose Refactor to continue.

  4. Move the method to a new class named ConsoleHand (in the same com.r2ha.blackjack package) by using the Refactor > Move Members action, or the F6 key.

Be sure to run the tests and make sure they all pass before continuing.

B. Repeat for Hand's Display

In this section, we'll move the method that displays the entire Hand's set of cards over to the ConsoleHand class.

  1. Write a characterization test for Hand's display() method. Since it doesn't return anything, you will have to refactor it to split it into two methods:

    • One method that returns a String (you can name it cardsAsString), do this with Extract Method.

    • Another that displays that String on the console using System.out.println, this will be display(), after the above method is extracted.

      Two Cards

      Be sure to add two cards to the Hand for this test to ensure you capture the behavior of a two-card Hand.

  2. Create a public query method (named cards()) on the Hand class that returns a List<Card>, so that it will be accessible by the cardsAsString method after it's moved.

    Queries Don't Return Internal Information

    Since we want to continue to encapsulate Hand's list, be sure to return a copy of the internal collection. We'll cover why in the walk-through of the solution.

  3. Refactor the cardsAsString() method to be static and then use the Move [Static] Members refactoring (F6) to move it to ConsoleHand.

  4. Get rid of the System.out.println reference in the display() method by inlining that method (Cmd Option N on Mac, Ctrl Alt N on Windows) into Game.

    • Yes, this just moves the "impurity" to another class, but we'll purify Game soon enough.

C. Complete "Purification" for Hand

Since displayValue() also returns a String that's meant for console output, we need to remove it to complete the purification of the Hand class. You will have to make the tradeoff between hiding the value() method, and purifying the class. Remember that pure domain outweighs the desire for encapsulation.

Once you remove the displayValue() method, and expose the value(), what tests might be changed to be easier to work with?

Find them by searching for usages (Cmd B on Mac, Ctrl B on Windows). Update them as needed and make sure they still pass.

Are We Done?

Have we removed all printlns and Strings? If so, we're done.

Make sure all the tests pass before declaring your work complete!


You're Done

That's the end of this lab. Well done!

If you want to compare your solution with mine, you can checkout from the repository on GitHub using the tag lab2-solution.

git checkout lab2-solution