...
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(resultexpectedResult.get(0).getTopicName(), expectedResultresult.get(0).getTopicName()); assertEquals(resultexpectedResult.get(0).getTopScore(), expectedResultresult.get(0).getTopScore() ); }
And here is the implementation class
Code Block language c# 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 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 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# 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.
...
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 | ||
---|---|---|
| ||
[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 | ||
---|---|---|
| ||
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 |
...