Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Implement this second test

  2. Code Block
    languagejava
       @Test
       public void find_heighest_score_with_array_of_one_return_array_of_one()
       {
           // Arrange
           int[] scores = { 56, 67, 45, 89 };
           String topicName = "Physics";
           ArrayList<TopicScores> topicScores = new ArrayList<>();
           topicScores.add(new TopicScores(topicName, scores));
       
           TopicManager cut = new TopicManager();
           ArrayList<TopicTopScore> expectedResult = new ArrayList<>();
           expectedResult.add(new TopicTopScore(topicName, 89));
    
           // Act
           ArrayList<TopicTopScore> result = cut.findTopicHighScores(topicScores);
    
           assertEquals(resultexpectedResult.get(0).getTopicName(), expectedResultresult.get(0).getTopicName());
           assertEquals(resultexpectedResult.get(0).getTopScore(), expectedResultresult.get(0).getTopScore() );
       }
  3. And here is the implementation class

  4. Code Block
    languagec#
    class TopicManager
    {
       private final HighestNumberFinder highestNumberFinder = new HighestNumberFinder();
    
       ArrayList<TopicTopScore> findTopicHighScores(ArrayList<TopicScores> array)
       {
          ArrayList<TopicTopScore> topScores = new ArrayList<>();
    
          if(array.size() == 1)
          {
              TopicScores ts = array.get(0);
              int topScore = highestNumberFinder.findHighestNumber(ts.getScores());
    
              topScores.add(new TopicTopScore(ts.getTopicName(), topScore));
          }
          return topScores;
       }
    }
  5. Updated TopicScores.java

  6. Code Block
    package com.s2s.demos.topicmanager;
    
    public class TopicScores
    {
       private String topicName;
       private int[] scores;
       
       public TopicScores(String topicName, int[] scores)
       {
          this.topicName = topicName;
          this.scores = scores;
       }
       
       public String   getTopicName()
       {
          return topicName;
       }
       
       public   int[] getScores()
       {
          return scores;
       }
    }
  7. Updated TopicTopScores.java

  8. Code Block
    public class TopicTopScore
    {
       private  String topicName;
       private  int topScore;
    
       public TopicTopScore(String topicName, int score)
       {
          this.topScore = score;
          this.topicName = topicName;
       }
       
       public String getTopicName()
       {
          return topicName;
       }
    
       public int getTopScore()
       {
          return topScore;
       }
    }
  9. Looking back at TopicManager, Line 3 represents the elephant in the code

    1. We already have tests for the HighestNumberFinder class, and yes class TopicManager requires HighestNumberFinder. But the coupling between these two classes is such that we cannot test TopicManger independently of HighestNumberFinder. Actually, this is a code smell.

    2. we can not substitute out HighestNumberFinder, this also is a code smell.

    3. We can remove the code smell by injecting HighestNumberFinder into TopicManager, when TopicManager is created.

  10. Modify TopicManager as follows

    1. remove the creation of HighestNumberFinder at line 5

    2. Pass an instance of a HighestNumberFinder into TopicManager as a constructor parameter

  11. Code Block
    languagec#
    public class TopicManager
    {
        private HighestNumberFinder highestNumberFinder;
    
        public  TopicManager( HighestNumberFinder hnf )
        {
            highestNumberFinder = hnf;
        }
    
        public TopicTopScore[] findTopicHighScores(TopicScores[] array)
        {
            if(array.Length == 1)
            {
                List<TopicTopScore> topScores = new List<TopicTopScore>();
    
                TopicScores ts = array[0];
                int topScore = highestNumberFinder.findHighestNumber(ts.Scores);
    
                topScores.Add(new TopicTopScore(ts.TopicName, topScore));
    
                return topScores.ToArray();
            }
            else
                return Array.Empty<TopicTopScore>();
        }
    }
  12. Refactor the tests so that they run. You should not have to change any of the test data.

...

Code Block
   @Test
   public void find_heighest_score_with_array_of_one_return_array_of_one_using_stub()
   {
       // Arrange
       int[] scores = { 56, 67, 45, 89 };
       String topicName = "Physics";
       ArrayList<TopicScores> topicScores = new ArrayList<>();
       topicScores.add(new TopicScores(topicName, scores));
   
       // Use a stub version of HighestNumberFinder
       com.s2s.demos.topicmanager.HighestNumberFinder hnf = 
                        new com.s2s.demos.topicmanager.HighestNumberFinder();
       TopicManager cut = new TopicManager(hnf);
       ArrayList<TopicTopScore> expectedResult = new ArrayList<>();
       expectedResult.add(new TopicTopScore(topicName, 89));

       // Act
       ArrayList<TopicTopScore> result = cut.findTopicHighScores(topicScores);

       
       assertEquals(resultexpectedResult.get(0).getTopicName(), expectedResultresult.get(0).getTopicName());
       assertEquals(resultexpectedResult.get(0).getTopScore(), expectedResultresult.get(0).getTopScore() );
   }

There will be a number of errors in the code, we will eliminate them one by one

Here is the Stub you will use (create it in the test folder - it’s not production code)

...

Tip

The tests have given us the confidence to refactor the code and begin to think more clearly about our implementation.

Now let’s substitute a stub in place of the real implementation of HighestNumberFinder.

...

Create a new called find_heighest_score_with_array_of_one_return_array_of_one_using_stub(), it's a copy of find_heighest_score_with_array_of_one_return_array_of_one()

...

Code Block
languagec#
        [Test]
        public void find_heighest_score_with_array_of_one_return_array_of_one_using_stub()
        {
            // Arrange
            int[] scores = { 56, 67, 45, 89 };
            string topicName = "Physics";
            TopicScores[] topicScores = { new TopicScores(topicName, scores) };
            IHighestNumberFinder hnf = new FindHighestNumberServiceFinal.HighestNumberFinder();
            TopicManager cut = new TopicManager(hnf);
            TopicTopScore[] expectedResult = { new TopicTopScore(topicName, 89) };

            // Act
            TopicTopScore[] result = cut.findTopicHighScores(topicScores);

            // Assert
            Assert.AreEqual(result[0].TopicName, expectedResult[0].TopicName);
            Assert.AreEqual(result[0].TopScore, expectedResult[0].TopScore);
        }
    }

...

Modify line 8 to

...

Code Block
languagec#
    IHighestNumberFinder hnf = new TopicManagerService.HighestNumberFinder();

...

The error is because of TopicManagerTests.HighestNumberFinder does not implement the IHighestNumberFinder interface. Modify it so that it does.

...

.

Info

We’ve now created a controlled environment for our tests

...