-
Notifications
You must be signed in to change notification settings - Fork 8
Mock api #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: mocking
Are you sure you want to change the base?
Mock api #9
Changes from all commits
3c4f2dd
2b5b0d9
94949ab
8fd71f7
e764636
918c504
413e660
72e20c0
954fdc8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,18 +12,32 @@ | |
| import edu.mills.cs180a.wordnik.client.model.WordOfTheDay; | ||
| import javafx.collections.ObservableList; | ||
|
|
||
| /** | ||
| * Create sample data to display on the list in JavaFX. | ||
| * | ||
| * @author Ellen Spertus | ||
| * @author Makie Maekawa | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent! I didn't even ask for people to add class-level javadoc. I should have. |
||
| * | ||
| */ | ||
| public class SampleData { | ||
| @VisibleForTesting | ||
| protected static final String WORD_KEY = "word"; | ||
| @VisibleForTesting | ||
| protected static final String FREQ_COUNT_KEY = "count"; | ||
| @VisibleForTesting | ||
| protected static final String FREQ_YEAR_KEY = "year"; | ||
| private static final int FREQ_YEAR = 2012; | ||
| @VisibleForTesting | ||
| protected static final int FREQ_YEAR = 2012; | ||
| private static ApiClient client; // set in fillSampleData() | ||
|
|
||
| @VisibleForTesting | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reordering the code made it harder to review. |
||
| protected static int getFrequencyByYear(WordApi wordApi, String word, int year) { | ||
| FrequencySummary fs = wordApi.getWordFrequency(word, "false", year, year); | ||
| return getFrequencyFromSummary(fs, year); | ||
| } | ||
|
|
||
| private static int getFrequencyFromSummary(FrequencySummary fs, int year) { | ||
| List<Object> freqObjects = fs.getFrequency(); | ||
| // freqObjects is a List<Map> [{"year" = "2012", "count" = 179}] for "Java" | ||
|
|
||
| if (freqObjects instanceof List) { | ||
| List<Object> maps = (List<Object>) freqObjects; | ||
| for (Object map : maps) { | ||
|
|
@@ -42,44 +56,65 @@ private static int getFrequencyFromSummary(FrequencySummary fs, int year) { | |
| return 0; | ||
| } | ||
|
|
||
| // TODO: Move to spring-swagger-wordnik-client | ||
| @VisibleForTesting | ||
| protected static int getFrequencyByYear(WordApi wordApi, String word, int year) { | ||
| FrequencySummary fs = wordApi.getWordFrequency(word, "false", year, year); | ||
| return getFrequencyFromSummary(fs, year); | ||
| public static List<Object> getDefinitions(WordsApi WordsApi) { | ||
| return WordsApi.getWordOfTheDay().getDefinitions(); | ||
| } | ||
|
|
||
| private static WordRecord buildWordRecord(String word, Map<Object, Object> definition) { | ||
| WordApi wordApi = client.buildClient(WordApi.class); | ||
| return new WordRecord( | ||
| word, | ||
| getFrequencyByYear(wordApi, word, FREQ_YEAR), | ||
| definition.get("text").toString()); | ||
| @VisibleForTesting | ||
| public static String getWord(WordsApi WordsApi) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should never have a variable name with the same name as a type. I'm surprised that Java allows this. Also, argument names should be lowerCamelCase.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't need this method. Instead, call a method in |
||
| return WordsApi.getWordOfTheDay().getWord(); | ||
| } | ||
|
|
||
| protected static WordOfTheDay getWordOfTheDay(WordsApi WordsApi) { | ||
| return WordsApi.getWordOfTheDay(); | ||
| } | ||
|
|
||
| /** | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You weren't asked to create javadoc for this method, which should be |
||
| * Get definitions and create WordRecord data. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The description isn't accurate. A better one would be "Add the word of the day to the list of sample words." |
||
| * | ||
| * @param wordsApi API key client. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be no period at the end of |
||
| * @return Return data to be displayed on the screen. return null, if definitions is null or | ||
| * empty. | ||
| */ | ||
| public static WordRecord addWordOfTheDay(WordsApi wordsApi) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method should be |
||
| List<Object> definitions = getWordOfTheDay(wordsApi).getDefinitions(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should not call |
||
| if (definitions != null && !definitions.isEmpty()) { | ||
| Object definition = definitions.get(0); | ||
| if (definition instanceof Map) { | ||
| @SuppressWarnings("unchecked") | ||
| Map<Object, Object> definitionAsMap = (Map<Object, Object>) definition; | ||
| return (buildWordRecord(getWordOfTheDay(wordsApi).getWord(), definitionAsMap)); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
|
|
||
| /** | ||
| * Create sample data for display on the list. | ||
| * | ||
| * @param backingList A list that allows listeners to track when something changes. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do not capitalize parameter descriptions. |
||
| */ | ||
| public static void fillSampleData(ObservableList<WordRecord> backingList) { | ||
| try { | ||
| client = ApiClientHelper.getApiClient(); | ||
| WordsApi wordsApi = client.buildClient(WordsApi.class); | ||
| WordOfTheDay word = wordsApi.getWordOfTheDay(); | ||
| List<Object> definitions = word.getDefinitions(); | ||
| if (definitions != null && !definitions.isEmpty()) { | ||
| Object definition = definitions.get(0); | ||
| if (definition instanceof Map) { | ||
| @SuppressWarnings("unchecked") | ||
| Map<Object, Object> definitionAsMap = (Map<Object, Object>) definition; | ||
| backingList.add(buildWordRecord(word.getWord(), definitionAsMap)); | ||
| } | ||
| } | ||
| backingList.add(addWordOfTheDay(wordsApi)); | ||
| } catch (IOException e) { | ||
| System.err.println("Unable to get API key."); | ||
| } | ||
|
|
||
| backingList.add(new WordRecord("buffalo", 5153, "The North American bison.")); | ||
| backingList.add(new WordRecord("school", 23736, "A large group of aquatic animals.")); | ||
| backingList.add(new WordRecord("Java", | ||
| 179, "An island of Indonesia in the Malay Archipelago")); | ||
| backingList.add(new WordRecord("random", | ||
| 794, "Having no specific pattern, purpose, or objective")); | ||
| backingList.add( | ||
| new WordRecord("Java", 179, "An island of Indonesia in the Malay Archipelago")); | ||
| backingList.add( | ||
| new WordRecord("random", 794, "Having no specific pattern, purpose, or objective")); | ||
| } | ||
|
|
||
| protected static WordRecord buildWordRecord(String word, Map<Object, Object> definition) { | ||
| WordApi wordApi = client.buildClient(WordApi.class); | ||
| return new WordRecord(word, getFrequencyByYear(wordApi, word, FREQ_YEAR), | ||
| definition.get("text").toString()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,33 +1,63 @@ | ||
| package edu.mills.cs180a.wordui.model; | ||
|
|
||
| import static edu.mills.cs180a.wordui.model.SampleData.FREQ_COUNT_KEY; | ||
| import static edu.mills.cs180a.wordui.model.SampleData.FREQ_YEAR; | ||
| import static edu.mills.cs180a.wordui.model.SampleData.FREQ_YEAR_KEY; | ||
| import static edu.mills.cs180a.wordui.model.SampleData.getFrequencyByYear; | ||
| import static edu.mills.cs180a.wordui.model.SampleData.getWordOfTheDay; | ||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
| import static org.mockito.ArgumentMatchers.anyInt; | ||
| import static org.mockito.ArgumentMatchers.anyString; | ||
| import static org.mockito.Mockito.mock; | ||
| import static org.mockito.Mockito.when; | ||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.LinkedHashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.CsvSource; | ||
| import edu.mills.cs180a.wordnik.client.api.WordApi; | ||
| import edu.mills.cs180a.wordnik.client.api.WordsApi; | ||
| import edu.mills.cs180a.wordnik.client.model.FrequencySummary; | ||
| import edu.mills.cs180a.wordnik.client.model.WordOfTheDay; | ||
|
|
||
| class SampleDataTest { | ||
| private final WordApi mockWordApi = mock(WordApi.class); | ||
| private static final Map<String, FrequencySummary> FREQS_MAP = Map.of( | ||
| "apple", makeFrequencySummary(List.of(makeMap(2000, 339), makeMap(2001, 464))), | ||
| "orange", makeFrequencySummary(List.of(makeMap(2000, 774), makeMap(2001, 941)))); | ||
| private final WordsApi mockWordsApi = mock(WordsApi.class); | ||
| private static final Map<String, FrequencySummary> FREQS_MAP = Map.of("apple", | ||
| makeFrequencySummary(List.of(makeMap(2000, 339), makeMap(2001, 464))), "orange", | ||
| makeFrequencySummary(List.of(makeMap(2000, 774), makeMap(2001, 941))), "blueberry", | ||
| makeFrequencySummary(List.of(makeMap(2000, 10), makeMap(2001, 58))), "airplane", | ||
| makeFrequencySummary(List.of(makeMap(2012, 353)))); | ||
|
|
||
| private static final WordOfTheDay MOCK_WORD = makeWordOfTheDay("airplane", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good, but I would call it |
||
| List.of("Any of various winged vehicles capable of flight, " | ||
| + "generally heavier than air and driven by jet engines or propellers.")); | ||
|
|
||
| private static final List<Object> DIFINITION_MAP = new ArrayList<Object>( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| Arrays.asList(makeMapDefin("Any of various winged vehicles capable of flight," | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You shouldn't repeat a string. You should put it in a constant. |
||
| + "generally heavier than air and driven by jet engines or propellers."))); | ||
|
|
||
| private static final WordRecord MOCK_WORDRECORD = | ||
| new WordRecord("airplane", 353, "Any of various winged vehicles capable of flight," | ||
| + "generally heavier than air and driven by jet engines or propellers."); | ||
|
|
||
| @BeforeEach | ||
| void setup() { | ||
| when(mockWordApi.getWordFrequency(anyString(), anyString(), anyInt(), anyInt())) | ||
| .thenAnswer(invocation -> FREQS_MAP.get(invocation.getArgument(0))); | ||
| when(mockWordsApi.getWordOfTheDay()).thenReturn(MOCK_WORD); | ||
| when(mockWordsApi.getWordOfTheDay().getWord()).thenReturn("blueberry"); | ||
| when(mockWordsApi.getWordOfTheDay().getDefinitions()) | ||
| .thenReturn(List.of("Any of various plants of the genus")); | ||
| } | ||
|
|
||
| private static Map<Object, Object> makeMap(int year, int count) { | ||
| return Map.of(SampleData.FREQ_YEAR_KEY, String.valueOf(year), | ||
| SampleData.FREQ_COUNT_KEY, count); | ||
| return Map.of(FREQ_YEAR_KEY, String.valueOf(year), FREQ_COUNT_KEY, count); | ||
| } | ||
|
|
||
| private static FrequencySummary makeFrequencySummary(List<Object> freqs) { | ||
|
|
@@ -36,10 +66,55 @@ private static FrequencySummary makeFrequencySummary(List<Object> freqs) { | |
| return fs; | ||
| } | ||
|
|
||
| private static Map<Object, Object> makeMapDefin(String defin) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A better name would be |
||
| Map<Object, Object> map = new LinkedHashMap<>(Map.of("text", String.valueOf(defin))); | ||
| return map; | ||
| } | ||
|
|
||
| @ParameterizedTest | ||
| @CsvSource({"apple,2000,339", "apple,2001,464", "apple,2020,0", "orange,2000,774", | ||
| "orange,2001,941", "orange,2050,0"}) | ||
| void testGetFrequencyFromSummary(String word, int year, int count) { | ||
| assertEquals(count, SampleData.getFrequencyByYear(mockWordApi, word, year)); | ||
| "orange,2001,941", "orange,2050,0", "airplane,2012,353"}) | ||
| void getFrequencyByYear_Equal_correctValue(String word, int year, int count) { | ||
| assertEquals(count, getFrequencyByYear(mockWordApi, word, year)); | ||
| } | ||
|
|
||
| private static WordOfTheDay makeWordOfTheDay(String word, List<Object> defin) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good helper method.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be clear to make the second argument a |
||
| WordOfTheDay wd = mock(WordOfTheDay.class); | ||
| when(wd.getWord()).thenReturn(word); | ||
| when(wd.getDefinitions()).thenReturn(defin); | ||
| return wd; | ||
| } | ||
|
|
||
| @Test | ||
| void getWord_Equal_correctValue() { | ||
| assertEquals("blueberry", getWordOfTheDay(mockWordsApi).getWord()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDefinitions_Equal_correctValue() { | ||
| assertEquals("Any of various plants of the genus", | ||
| getWordOfTheDay(mockWordsApi).getDefinitions().get(0)); | ||
| } | ||
|
|
||
| @SuppressWarnings("static-access") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than suppressing warnings, you should deal with the underlying issue, which I'm happy to discuss. |
||
| @Test | ||
| void addWordOfTheDay_Equal_correctValue() { | ||
| SampleData sd = mock(SampleData.class); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no need to mock the class. |
||
| when(sd.getWordOfTheDay(mockWordsApi).getDefinitions()).thenReturn(DIFINITION_MAP); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should not mock within the test. |
||
| when(sd.getWordOfTheDay(mockWordsApi).getWord()).thenReturn("airplane"); | ||
|
|
||
| List<Object> getDefin = sd.getWordOfTheDay(mockWordsApi).getDefinitions(); | ||
| Object definition = getDefin.get(0); | ||
| @SuppressWarnings("unchecked") | ||
| Map<Object, Object> definitionAsMap = (Map<Object, Object>) definition; | ||
|
|
||
| WordRecord testWordRecord = new WordRecord( | ||
| sd.getWordOfTheDay(mockWordsApi).getWord(), getFrequencyByYear(mockWordApi, | ||
| sd.getWordOfTheDay(mockWordsApi).getWord(), FREQ_YEAR), | ||
| definitionAsMap.get("text").toString()); | ||
|
|
||
| assertTrue(MOCK_WORDRECORD.getWord().equals(testWordRecord.getWord()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should have a series of |
||
| && MOCK_WORDRECORD.getFrequency().equals(testWordRecord.getFrequency()) | ||
| && MOCK_WORDRECORD.getDefinition().equals(testWordRecord.getDefinition())); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes to this file are all due to formatting. You should keep this type of change out of PRs. The best way to do so it to look at your PR on GitHub before submitting it.