...
Implement this second test
Code Block language java @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(expectedResult.get(0).getTopicName(), result.get(0).getTopicName()); assertEquals(expectedResult.get(0).getTopScore(), result.get(0).getTopScore() ); }
And here is the implementation class
Code Block language c#java 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; } }
Updated TopicScores.java
Code Block language java 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; } }
Updated TopicTopScores.java
Code Block language java 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; } }
Looking back at TopicManager,
Line 3
represents the elephant in the codeWe already have tests for the
HighestNumberFinder
class, and yes classTopicManager
requiresHighestNumberFinder
. But the coupling between these two classes is such that we cannot testTopicManger
independently ofHighestNumberFinder
. Actually, this is a code smell.we can not substitute out
HighestNumberFinder
, this also is a code smell.We can remove the code smell by injecting
HighestNumberFinder
intoTopicManager
, whenTopicManager
is created.
Modify
TopicManager
as followsremove the creation of
HighestNumberFinder
at line 5Pass an instance of a
HighestNumberFinder
intoTopicManager
as a constructor parameter
Code Block language c#java 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>(); } }
Refactor the tests so that they run. You should not have to change any of the test data.
...