-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Add more unit tests to three gui classes #7636
Conversation
…ngxie1991-a3-nx * 'a3-nx' of https://github.com/ningxie1991/jabref: fix checkstyle issue and comment out the use of Globals Modified the tests modified the tests organized imports Add JUnit test with mocks for CopyMoreAction Added two Junit tests using mocks for the gui
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.
Thanks again for the good work!
@calixtus can you take a look at the Globals.prefs extraction? |
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.
Some questions about the tests, and some clearification about the fileDirforDatabase variable.
Extraction of Globals.prefs looks good.
@Override | ||
public FileLinkPreferences getFileLinkPreferences() { | ||
return new FileLinkPreferences( | ||
get(MAIN_FILE_DIRECTORY), // REALLY HERE? | ||
fileDirForDatabase); | ||
} | ||
|
||
@Override | ||
public void storeFileDirforDatabase(List<Path> dirs) { | ||
this.fileDirForDatabase = dirs; | ||
} | ||
|
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.
getFileLinkPreferences
needs to be removed in the future as well as the variable fileDirForDatabase
, since this is some pretty dirty hack from earlier times in JabRef that needs to be done right sometime. So changing something here is lost effort. Furthermore storeFileDirforDatabase
does not persistently store a variable, therefor the naming scheme get/store should not be used here.
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.
Maybe this variable is better located in the stateManager? @tobiasdiez
FileLinkPreferences getFileLinkPreferences(); | ||
|
||
void storeFileDirforDatabase(List<Path> dirs); | ||
|
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.
please remove this
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.
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.
Yes. This setter is no fix for the hack, but a disguise.
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.
Keep it ugly, until it's fixed. 😏
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.
Sure I would, but it needs to be present in the preferences Service, because we need to get rid of the Globals for the test, as we cannot mock it.
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.
I would vote to create a follow up PR to fix this
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.
Yes, a follow-up is most urgent needed, but there was a reason for that hack, I'm afraid, there is no easy fix for this. See declaration of this:
// The following field is used as a global variable during the export of a database.
// By setting this field to the path of the database's default file directory, formatters
// that should resolve external file paths can access this field. This is an ugly hack
// to solve the problem of formatters not having access to any context except for the
// string to be formatted and possible formatter arguments.
public List<Path> fileDirForDatabase;
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.
But to say that again with most deep concern: The proposed change, to put these two methods into the preferencesService shall not happen!
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.
After careful consideration: @Siedlerchr and me think it would be right, to keep the changes as SiedlerChr added, since extracting this mess of a temp variable in the preferences totally exploding this PR. This calls for a distinct one. Good luck, @Siedlerchr 😆
copyMoreAction.execute(); | ||
|
||
verify(clipBoardManager, times(0)).setContent(any(String.class)); | ||
verify(dialogService, times(1)).notify(Localization.lang("None of the selected entries have titles.")); |
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.
I thought I remember that junit provides something like any()
as an argument replacement, since dealing with translations in tests that are not especially tailored for language test can mess things quickly up.
|
||
String copiedTitles = String.join("\n", titles); | ||
verify(clipBoardManager, times(1)).setContent(copiedTitles); | ||
verify(dialogService, times(1)).notify(Localization.lang("Warning: %0 out of %1 entries have undefined title.", |
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.
Same here: can the localized argument be exchanged with something generic?
There are more below...
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.
Yes, any()
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.
Yes, they can by just any() but because each test is testing for a specific condition, for example when no entries have titles, or when some entries have titles. In different cases, the diaglogService notitfy shows different corresponding messages. I thought it would be better to specify the messages that we are verifying, otherwise the verify dialogService kind of loses its purpose if we use any() as the argument? I am not sure if verifying that dialogService gets invoked is enough in this test. If so, I can definitely switch them to any() arguments. @calixtus
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.
I think it's okay to test the correct invocation. I think @calixtus and I thought verify only check with times the number of invovations.
String copiedTitles = String.join("\n", titles); | ||
verify(clipBoardManager, times(1)).setContent(copiedTitles); | ||
verify(dialogService, times(1)).notify(Localization.lang("Copied '%0' to clipboard.", | ||
JabRefDialogService.shortenDialogMessage(copiedTitles))); |
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.
Test is becoming pretty complicated: in fact you are also testing the shortenDialogMessage-method here too...
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.
Oh yes, I just realized this shortenDialogMessage method is being tested as well. However, as I mentioned in a comment above, the reason why I used specific localized argument was because the tests are meant to verify if dialogSerivce is showing the correct message under each condition. Maybe here I can just simply use any() as the mocked argument since it's too complicated.
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.
I think it's okay.
@ningxie1991 Would be nice if you could address the hints related to the test. You can use mockito's any method without specifying the exact localization content etc |
* upstream/main: (354 commits) Fix ScienceDirect fetcher (#7684) Refactor NoBibTexFieldCheckerTest to increase mutation coverage (#7697) Update Gradle from 6.8.3 to 7.0 (#7619) Fixes Jabref#7305: the RFC fetcher is not compatible with the draftFix for issue 7305 (#7674) Refactoring existing unit tests (#7693) cover boundary cases & add more unit tests (#7694) Bump classgraph from 4.8.104 to 4.8.105 (#7688) Bump java-diff-utils from 4.9 to 4.10 (#7692) Fix arXiv fetcher tests (#7686) Make key for ScienceDirect configurable (#7683) migration of timestamp (#7671) Fix CCSB and DOAJ (#7426) [Bot] Update CSL styles (#7680) MS Office XML: Export month name (#7677) linkfix (#7678) readd fix (#7675) Fix threading cleanup in performSearch (#7672) add missing changelog delete bug fix (#7580) Add more unit tests to three gui classes (#7636) ... # Conflicts: # build.gradle
This pull request replaces #7635 (closed/not merged), and it contributes to issue #6207, which is to add more unit tests to the project, in this case specifically in the gui package using test doubles.
Tests added:
NewEntryActionTest
CopyMoreActionTest
ExportToClipboardActionTest
In order to add the ExportToClipboardActionTest and to migrate to using PreferencesService, code refactoring has been done as suggested by @Siedlerchr. The purpose of the refactoring is to add PreferencesService as a parameter in the constructors of ExportToClipboardAction to replace the Globals variable. Refactored classes are as follows:
ExportToClipboardAction.java
JabRefFrame.java
RightClickMenu.java
JabRefPreferences.java
PreferencesService.java
CHANGELOG.md
described in a way that is understandable for the average user (if applicable)