Mockito test overwritten void method - java

I'm new to java, unit-testing and mockito but I want to test something from my class.
Class I want to test:
abstract class Irc {
Command received(String data) {
// parsing
receivedCommand(prefix, command, parameters, trailing, tags);
return new Command(prefix, command, parameters, trailing, tags);
}
private void receivedCommand(String prefix, String command, String[] parameters, String trailing, Map<String, String> tags) {
String nick = getNickFromPrefix(prefix);
parsed(prefix, command, parameters, trailing);
if (command.equals("MODE")) {
if (parameters.length == 3) {
String chan = parameters[0];
String mode = parameters[1];
String name = parameters[2];
if (mode.length() == 2) {
String modeChar = mode.substring(1, 2);
if (mode.startsWith("+")) {
onModeChange(chan, name, true, modeChar, prefix);
} else if (mode.startsWith("-")) {
onModeChange(chan, name, false, modeChar, prefix);
}
}
}
return;
}
}
void onModeChange(String channel, String nick, boolean modeAdded, String mode, String prefix) {
}
}
EDIT:
I want to make sure that onModeChange is called after received was called.
What I have so far:
#Test
public void modeChangeReceivedRightSyntax() {
try {
irc = new Irc("Test") {
#Override
public void debug(String line) {
System.err.println(line);
}
#Override
void onModeChange(String channel, String nick, boolean modeAdded, String mode, String prefix) {
System.out.println("Mode Change: " + channel + " " + nick + " " + mode + " " + prefix + " " + modeAdded);
}
};
ircMock = spy(irc);
when(
ircMock.received(":jtv MODE #channel +o user")
).thenReturn(
new Command("jtv", "MODE", new String[]{"#channel", "+o", "user"}, "", null)
);
verify(ircMock).onModeChange("#channel", "user", true, "o", "jtv");
} catch (Exception ex) {
fail("Exception: " + ex.toString());
}
}
The when is working but the verify fails with Actually, there were zero interactions with this mock.

Your code is not calling any business methods. It only mocks how the received method should behave but that does not actually call the method.
Since your Irc class is abstract, your approach to use spy is good but you should not mock the received method but tell the spy to delegate to the real method. Then you can verify that onModeChange is called.
Irc irc = spy(Irc.class, withSettings().defaultAnswer(CALLS_REAL_METHODS));
// Business method
irc.received(":jtv MODE #channel +o user");
// Asserts
verify(irc).onModeChange("#channel", "user", true, "o", "jtv");

Related

Access arraylist from another class without "return" Assert.fail(); unable to access return

I have read all similar question but nothing help.
how to access arraylist from another class without "return"
Test Fail is not returning failedtest
As I have Assert.fail(); under same method which I need return value.
Please help me find solution for if any alternative way to access arraylist .
public class FrontPage extends SeleniumUtils implements IHomePage {
public List<String> failedtest = new ArrayList<String>();
public List<String> CheckSummaryExposure(WebDriver driver, String actualView, String viewName) throws InterruptedException {
String[] actualViews = actualView.split(",");
List<String> views = new ArrayList<>();
boolean flag = false;
for (int i = 0; i < actualViews.length; i++) {
if (views.get(i).equals(actualViews[i].trim().toString())) {
Add_Log.info("Successfully displayed " + viewName);
Reporter.log("Successfully displayed " + viewName);
} else {
Add_Log.info(" filter criteria is not displayed " + viewName);
Reporter.log(" filter criteria is not displayed " + viewName);
failedtest.add(" filter criteria is not displayed " + viewName);
flag = true;
}
}
if (flag) {
TestResultStatus.Testfail = true;
// Test Fail is not returning failedtest
Assert.fail();
} else {
Add_Log.info("Successfully all filter);
Reporter.log("Successfully all filter);
}
System.out.println("PRINT FAIL SENTENCE");
System.out.println(failedtest);
return failedtest;
}
other class [Sanity_TC] to call FrontPage class, method CheckSummaryExposure with return failedtest
public class Sanity_TC extends SuiteBase {
static public HashMap<String, String> Remark = new HashMap<>();
List<String> failedtest =null;
#Test(dataProvider = "SanityTCTest", dataProviderClass = utility.Xlsdataprovider.class, groups = "Dashboard", alwaysRun = true)
public void Sanity_TC015(LinkedHashMap<String, String> data) throws InterruptedException, SQLException {
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
loadWebBrowser();
objLoginPage.login(getDriver(), username, password, URLs.get(Key), Instance);
String result = String.join("-",FP.CheckSummaryExposure(getDriver(), actualViews, viewName));
Remark.put(methodName, result);

How to provide Object as well as String in the data provider for TestNG

I have few dependent TCs grouped together.
The TC2 has some data of its own and also dependent on some of the data from TC1.
I am unable to provide an array of Object along with String in the data provider.
I tried by providing a mix of Object and String in data provider.
#DataProvider(name="mydataprovider")
protected Object[][] dataprovider(){
Object[][] returnObj = new Object[this.classObject.size()][];
for(int index=0; index < this.classObject.size(); index++) {
returnObj[index] = new Object[]{this.classObject.get(index)};
}
return new Object[][]{
{"name","position"}, {returnObj}
};
}
#Test(dataProvider="mydataprovider", dependsOnMethods = {"TC1"})
public void testMethod(String name, String position, MyClassData classData)
{
//Test Steps
}
I am facing the issue of Data provider mismatch
org.testng.internal.reflect.MethodMatcherException
You can pass anything to the methods, a simplified version of your code.
class MyClassData {
String abc;
MyClassData(String abc) {
this.abc = abc;
}
#Override
public String toString() {
return "MyClassData [abc=" + abc + "]";
}
}
#DataProvider(name="mydataprovider")
protected Object[][] dataprovider(){
MyClassData[] obj = new MyClassData[2];
obj[0] = new MyClassData("abc");
obj[1] = new MyClassData("def");
return new Object[][]{
{"name","position", obj}
};
//If you want to pass one obj as one param then, in which case your test method should accept MyClassData object instead of MyClassData[]
return new Object[][]{
{"name","position", obj[0]},
{"name","position", obj[1]},
};
}
#Test(dataProvider="mydataprovider")
public void testMethod(String name, String position, MyClassData[] classData)
{
System.out.println(name + " " + position + " " + classData[0]);
System.out.println(name + " " + position + " " + classData[1]);
//Test Steps
}

Trying to make use of Akka future and play promises in my Play2 application

When reading up on the play2 documentation I found this:
Because of the way Play 2.0 works, action code must be as fast as
possible (i.e. non blocking). So what should we return as result if we
are not yet able to compute it? The response should be a promise of a
result!
Wow! This of course made me interested in playakka and akka.
I'm currently building an autocomplete application that is integrating with elasticsearch,
so this would be a perfect fit!
Controller:
public class AutoComplete extends Controller {
#BodyParser.Of(value = BodyParser.Json.class)
public static Result complete(final String term) {
F.Promise<List<String>> list = Akka.future(new Callable<List<String>>() {
public List<String> call() throws Exception {
List<String> list = IndexService.find(term);
return list;
}
});
return async(list.map(new F.Function<List<String>, Result>() {
#Override
public Result apply(List<String> list) throws Throwable {
return ok(Json.toJson(list));
}
}));
}
Service:
public static List<String> find(final String term) {
IndexQuery < SearchWord > query = SearchWord.find.query();
query.setQuery("{\n" +
" \"bool\": {\n" +
" \"should\": [\n" +
" {\n" +
" \"text\": {\n" +
" \"search_word.ngrams\": {\n" +
" \"operator\": \"and\",\n" +
" \"query\": \""+term+"\"\n" +
" }\n" +
" }\n" +
" },\n" +
" {\n" +
" \"text\": {\n" +
" \"search_word.full\": {\n" +
" \"boost\": 1,\n" +
" \"query\": \""+term+"\"\n" +
" }\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}");
IndexResults<SearchWord> indexResults = SearchWord.find.search(query);
List<String> list = new ArrayList<String>();
for(SearchWord word : indexResults.getResults()){
list.add(word.getWord());
}
return list;
}
}
SearchWord:
#IndexType(name = "search_word")
public class SearchWord extends Index {
// Find method static for request
public static Index.Finder<SearchWord> find = new Index.Finder<SearchWord>(SearchWord.class);
public enum WordType {
NAME,
STRONG_SEARCH_WORD,
WEAK_SEARCH_WORD,
BANNED
}
private String word;
private WordType wordType;
public SearchWord() {
}
public SearchWord(IndexWord indexWord) {
super.id = ""+indexWord.getId();
this.word = StringUtils.lowerCase(indexWord.getWord());
this.wordType = WordType.valueOf(indexWord.getType());
}
public String getId() {
return super.id;
}
public void setId(String id) {
super.id = id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public WordType getWordType() {
return wordType;
}
public void setWordType(WordType wordType) {
this.wordType = wordType;
}
#Override
public Map toIndex() {
HashMap map = new HashMap();
map.put("id", super.id);
map.put("word", word);
map.put("word_type", wordType.toString());
return map;
}
#Override
public Indexable fromIndex(Map map) {
if (map == null) {
return this;
}
this.word = (String) map.get("word");
this.wordType = WordType.valueOf((String)map.get("word_type"));
return this;
}
}
The code works very well but I must say that I'm not that sure that I have implemented this correctly. I'm really struggling to understand the documentation.
So my questions are basically:
Have I implemented the Future and Promise correctly?
Would it be better to create a custom actor, and in that actor perform the index
search, like the example in the docs:
=====
return async(
Akka.asPromise(ask(myActor,"hello", 1000)).map(
new Function<Object,Result>() {
public Result apply(Object response) {
return ok(response.toString());
}
}
)
);
Maybe you have some great example that I have not found yet?
AFAIK, your code is totally ok.
I may be wrong, but I think that the second option is strictly equivalent to the first one, since the Akka.future() method is a wrapper around the Akka.promise() method.
From the Akka class source code of Play 2.0.4:
/**
* Executes a block of code asynchronously in the application Akka Actor system.
*/
public static <T> Promise<T> future(java.util.concurrent.Callable<T> callable) {
return asPromise(akka.dispatch.Futures.future(callable, system().dispatcher()));
}
Although you have correctly implemented the Promise and Future, i wouldn't consider this code to be "non-blocking"...
It seems that the blocking call is
List<String> list = IndexService.find(term);
and although this is now wrapped in a promise/future, it is still a blocking call...
If you want to be truly non-blocking (with all its benefits), you'll have to make your data access (queries) non-blocking...
Oh, and a non-blocking action method should return a Promise of a Result, not a Result...
This is how i should write your code:
#BodyParser.Of(value = BodyParser.Json.class)
public static F.Promise<Result> complete(final String term) {
scala.concurrent.Future<List<String>> listFuture = IndexService.find(term);
F.Promise<List<String>> listPromise = F.Promise.wrap(listFuture);
return listPromise.map(new F.Function<List<String>, Result>() {
#Override
public Result apply(List<String> list) throws Throwable {
return ok(Json.toJson(list));
}
});
}
Hope this helps!

What does this error mean: The method...is not applicable for the arguments

I'm new to this and I can't figure out what this error means.
I've tried googling but can't make any sense out of what I am finding.
I need to interact with an API to post a ticket to a remote server, and I got this code from a tutorial that I'm following.
In this block of code I'm getting this error:
The method postToRemoteServer(String) in the type HelpDeskTestService
is not applicable for the arguments (String, new
AsyncCallback(){})
sendButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
HelpDeskTestService.postToRemoteServer(
"http://xx.xx.xx.xx/sdpapi/request/",
new AsyncCallback<String>() {
#Override
public void onFailure(Throwable caught) {
Window.alert("Failure getting XML through proxy");
}
#Override
public void onSuccess(String result) {
processXML(result);
}
});
}
});
Here is the code from the synchronous interface:
public String postToRemoteServer(final String serviceUrl)
throws HelpDeskTestException;
Here is the code from the Asynchronous interface:
void postToRemoteServer(
final String serviceUrl,
AsyncCallback<String> callback);
And finally, here is the code from the implementation class:
#Override
public String postToRemoteServer(String serviceUrl)
throws HelpDeskTestException {
try {
//dividing url into host: http://some.server
//path: a/path/in/it
//and parameters: this=that&those=others
int hostStart= serviceUrl.indexOf("//");
int pathStart= serviceUrl.substring(hostStart + 2).indexOf("/");
int parameterStart= serviceUrl.substring(hostStart + 2 + pathStart).indexOf("?");
final String serverHost= serviceUrl.substring(0, hostStart + pathStart + 2);
final String serverPath= serviceUrl.substring(hostStart + 3,
hostStart + pathStart + 2 + parameterStart);
final String serverParameters= serviceUrl.substring(hostStart + pathStart + 3 + parameterStart);
final URL url = new URL(serverHost);
final URLConnection connection= url.openConnection();
connection.setDoOutput(true);
final OutputStreamWriter out= new OutputStreamWriter(connection.getOutputStream());
final BufferedReader in= new BufferedReader(new InputStreamReader(
connection.getInputStream()));
out.write("POST " + serverPath + "\r\n");
out.write("Host: " + serverHost + "\r\n");
out.write("Accept-Encoding: identity\r\n");
out.write("Connection: close\r\n");
out.write("Content-Type: application/x-www-form-urlencoded\r\n");
out.write("Content-Length: " + serverParameters.length() + "\r\n\r\n" +
serverParameters + "\r\n");
String result = "";
String inputLine;
while ((inputLine=in.readLine()) != null) {
result+= inputLine;
}
in.close();
out.close();
return result;
} catch (final Exception e) {
throw new HelpDeskTestException();
}
Any help will be appreciated.
You need to use the asynchronous interface when calling your service. You create an instance of it using GWT.create(). Assuming your asynchronous interface is called "HelpDeskTestServiceAsync", you would do something like this:
HelpDeskTestServiceAsync asyncService = GWT.create(HelpDeskTestService.class);
asyncService.postToRemoteServer(
"http://xx.xx.xx.xx/sdpapi/request/",
new AsyncCallback<String>() {
#Override
public void onFailure(Throwable caught) {
Window.alert("Failure getting XML through proxy");
}
#Override
public void onSuccess(String result) {
processXML(result);
}
});
Exactly what it says, you call it with a String and an ASyncCallback type. It needs to be called with only a String. See the API documentation on that method or the 'HelpDeskTestService' class for more informations on it's use.
The error means that the types of the argument expressions don't match the types of the method's formal parameters.
"The method postToRemoteServer(String) in the type HelpDeskTestService is not applicable for the arguments (String, new AsyncCallback(){})"
It is saying that you are trying to postToRemoteServer with two arguments, but it is declared as taking one argument.
It is not entirely clear why this is happening, but it looks like the you are calling a static method, and if that is the case the interfaces are moot.
Alternatively, if HelpDeskTestService is a variable (tsk, tsk ... Code style violation ... tsk, tsk) then the problem may be the variable's declared type. If you've declared it to be Synchronous, then the language won't permit you to all a method in the Asynchronous type ... unless Synchronous extends Asynchronous.

How to encapsulate the logic of parametrized messages?

I'm using java.util.resourcebundle to format my JSTL messages and this works fine:
I use the class MessageFormat you can see here. Now I want to encapsulate this to a method that is just getParametrizedMessage(String key, String[]parameters) but I'm not sure how to do it. Now there is quite a lot of work to display just one or two messages with parameters:
UserMessage um = null;
ResourceBundle messages = ResourceBundle.getBundle("messages");
String str = messages.getString("PF1");
Object[] messageArguments = new String[]{nyreg.getNummer()};
MessageFormat formatter = new MessageFormat("");
formatter.applyPattern(messages.getString("PI14"));
String outputPI14 = formatter.format(messageArguments);
formatter.applyPattern(messages.getString("PI15"));
String outputPI15 = formatter.format(messageArguments)
if(ipeaSisFlag)
if(checkIfPCTExistInDB && nyreg.isExistInDB()) {
//um = new ExtendedUserMessage(MessageHandler.getParameterizedMessage("PI15", new String[]{nyreg.getNummer()}) , UserMessage.TYPE_INFORMATION, "Info");
um = new ExtendedUserMessage(outputPI15 , UserMessage.TYPE_INFORMATION, "Info");
…and so on. Now can I move this logic to a static class MessageHandler.getParameterizedMessage that now is not working and looking like this:
private final static String dictionaryFileName="messages.properties";
public static String getParameterizedMessage(String key, String [] params){
if (dictionary==null){
loadDictionary();
}
return getParameterizedMessage(dictionary,key,params);
}
private static void loadDictionary(){
String fileName = dictionaryFileName;
try {
dictionary=new Properties();
InputStream fileInput = MessageHandler.class.getClassLoader().getResourceAsStream(fileName);
dictionary.load(fileInput);
fileInput.close();
}
catch(Exception e) {
System.err.println("Exception reading propertiesfile in init "+e);
e.printStackTrace();
dictionary=null;
}
}
How can I make using my parametrized messages as easy as calling a method with key and parameter?
Thanks for any help
Update
The logic comes from an inherited method that in in the abstract class that this extends. The method looks like:
protected static String getParameterizedMessage(Properties dictionary,String key,String []params){
if (dictionary==null){
return "ERROR";
}
String msg = dictionary.getProperty(key);
if (msg==null){
return "?!Meddelande " +key + " saknas!?";
}
if (params==null){
return msg;
}
StringBuffer buff = new StringBuffer(msg);
for (int i=0;i<params.length;i++){
String placeHolder = "<<"+(i+1)+">>";
if (buff.indexOf(placeHolder)!=-1){
replace(buff,placeHolder,params[i]);
}
else {
remove(buff,placeHolder);
}
}
return buff.toString();
}
I think I must rewrite the above method in order to make it work like a resourcebundle rather than just a dictionary.
Update 2
The code that seems to work is here
public static String getParameterizedMessage(String key, Object [] params){
ResourceBundle messages = ResourceBundle.getBundle("messages");
MessageFormat formatter = new MessageFormat("");
formatter.applyPattern(messages.getString(key));
return formatter.format(params);
}
I'm not really sure what you're trying to achive, here's what I did in the past:
public static final String localize(final Locale locale, final String key, final Object... param) {
final String name = "message";
final ResourceBundle rb;
/* Resource bundles are cached internally,
never saw a need to implement another caching level
*/
try {
rb = ResourceBundle.getBundle(name, locale, Thread.currentThread()
.getContextClassLoader());
} catch (MissingResourceException e) {
throw new RuntimeException("Bundle not found:" + name);
}
String keyValue = null;
try {
keyValue = rb.getString(key);
} catch (MissingResourceException e) {
// LOG.severe("Key not found: " + key);
keyValue = "???" + key + "???";
}
/* Message formating is expensive, try to avoid it */
if (param != null && param.length > 0) {
return MessageFormat.format(keyValue, param);
} else {
return keyValue;
}
}

Categories