I have a Tuple mock class, whose getString(0) and getString(1) methods are expected to be called n times. Instead of writing something like,
when(tuple.getString(0)).thenReturn(logEntries[0]).thenReturn(logEntries[1])...thenReturn(logEntries[n - 1])
manually, I tried the following:
OngoingStubbing stubbingGetStringZero = when(tuple.getString(0)).thenReturn(serviceRequestKey);
OngoingStubbing stubbingGetStringOne = when(tuple.getString(1)).thenReturn(logEntries[0]);
for (int i = 1; i < n; i++) {
stubbingGetStringZero = stubbingGetStringZero.thenReturn(serviceRequestKey);
stubbingGetStringOne = stubbingGetStringOne.thenReturn(logEntries[i]);
}
The expected result is that all calls to tuple.getString(0) should return the String serviceRequestKey and each call to tuple.getString(1) should return a different String logEntries[i] ie. ith invocation of tuple.getString(1) returns ith element of logEntries array.
However, due to some odd reason, things are getting mixed up, and second invocation to tuple.getString(1) returns the String serviceRequestKey instead of logEntries[1]. What am I missing here?
Well, the right way to do this would be:
import org.mockito.AdditionalAnswers;
String[] logEntry = // Some initialization code
List<String> logEntryList = Arrays.asList(logEntry);
when(tuple.getString(1)).thenAnswer(AdditionalAnswers.returnsElementsOf(logEntryList));
On each invocation, successive elements of logEntry array are returned. Thus, ith invocation of tuple.getString(1) returns ith element of logEntry array.
P.S: The example in documentation of returnsElementsOf (as of this writing) is not updated (it still uses ReturnsElementsOf example): http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/AdditionalAnswers.html#returnsElementsOf(java.util.Collection)it
If I understood well, you want your mock to return different results depending on the invocation (meaning result1 when invoked for the first time, result2 when invoked for the second time etc)- this can be accomplished with such thing
Mockito.when(tuple.getString(0)).thenReturn(serviceRequestKey,logEntries[0],logEntries[1])
With this you will get serviceRequestKey on first invocation, logEntries[0] on second etc...
If you want something more sophisticated, like change the return depending on the param in the method use thenAnswer() as shown here
Not sure I understand Mockito well enough to understand your example, but wouldn't you want something like:
Mockito.when(tuple.getString(0)).thenReturn(serviceRequestKey);
for(int i = 0;i < logEntries.length;i++) {
Mockito.when(tuple.getString(i+1)).thenReturn(logEntries[i]);
}
I know that post is older, but maybe it helps:
OngoingStubbing<Boolean> whenCollectionHasNext = when(mockCollectionStream.hasNext());
for (int i = 0; i < 2; i++) {
whenCollectionHasNext = whenCollectionHasNext.thenReturn(true);
}
whenCollectionHasNext = whenCollectionHasNext.thenReturn(false);
Related
This question might appear trivial, but I am unable to find a solution to this problem for a few days.
Snippet 1 :
for(int i = 0; i < arr.length; i++){
arr[i] = new Bucket();
}
Snippet 2 :
Arrays.fill(arr, new Bucket());
Code with snippet 1 is executing as expected, but code that includes snippet 2 is not passing all the test cases.
I am expecting both the statements to do the same work internally. But the test cases show it is not. Any help to clarify this will be very helpful.
Think about what they do: in the loop you create a new object on every iteration. In the second you create one object and fill the array with it. They are totally different.
From documentation:
Assigns the specified Object reference to each element of the specified array of Objects.
Arrays.fill() uses the same object all time:
public static void fill(Object[] a, Object val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
So entire array becomes filled with a single instance created once by new Bucket()
I am expecting both the statements to do the same work internally.
Snippet 2 is only creating one Bucket, and adding the same instance to every slot. So they are not the same, in Java 8+ you could use a lambda and something like
IntStream.range(0, arr.length).forEach(x -> arr[x] = new Bucket());
to fill the Bucket[] arr.
I have written a method with the aim to count the number of times a specific flavour of crisps appears in a snack machine in blueJ
public int countPacks(String flavour){
int n = 0;
int nrFlavour = 0;
while( n < packets.size()) {
if( packets.get(n).equals(flavour)){
nrFlavour++;
n++;
}
else n++;
}
return nrFlavour;
}
I have an Arraylist 'packets' which holds PackOfCrisps objects which have a specific flavour. However when I have added say three packets of "salt" flavour crisps and I run this method, inputting "salt" as the flavour, it just returns 0 as though there are no PackOfCrisps objects with flavour "salt".
Sorry if this doesn't make sense. I am very new to Java and I have tried to explain my problem the best I can. :)
The list packets holds PackOfCrisps objects, and the method takes a String parameter. So the statement packets.get(n).equals(flavour) is comparing a PackOfCrisps object to a String, hence the count variable will never increase.
You need to compare the flavour string to the specific field of the object, something like:
if(packets.get(n).getFlavour().equals(flavour)){
On a side note, you can replace the while loop with a simple for loop and remove the increment of n.
There is a built-in solution to your problem, you can use this method
You can rewrite your countPacks method like this :
public int countPacks(String flavour){
return Collections.frequency(packets, flavour);
}
Im trying to return an arraylist from the method getNumbers (which contains strings)
public ArrayList<String> getNumbers(){
return (numeros);
}
Then by using a searcher im trying to compare between a variable m (which contains the desired info to look for) and the returned list.
public class NumberSearcher {
Reader reader = new KeyboardReader();
public NumberSearcher(ArrayList<Contacto> contactos){
String m = reader.read();
for(int i = 0; i<contactos.size();i++){
if(contactos.get(i).getPhoneNumbers().contains(m)){
contactos.get(i).display();
}
}
}
}
I have succeded in creating a searcher using this very same style but only when using methods that return String alone.
The problem is its not working. If there there would be a match it should display the contact information but it seem it isnt "comparing" properly because nothing happens.
It's difficult to understand what you're asking here. Your getNumbers method doesn't get called from the second code block, so I don't see where that is relating to anything. It's also unclear what you mean the problem is. Can you try to give us a more detailed description of what is going wrong?
Anyways, I'll try to give you some general advice here, but without knowing the issue it's hard to say how much this will help.
Firstly, it is almost always recommended to have your method's return type as the List interface, rather than a specific implementation (ArrayList, etc). You can specify a return type from within the method but this way they client doesn't need to know what the underlying data structure is, and you are also flexible to future data structure changes.
public List<String> getNumbers(){
return (numeros);
}
Secondly, I would probably change the name 'getNumbers' to something slightly more precise - if I see a 'getNumbers' method I expect it to return some numeric entities, not a list of strings. If they are phone numbers then explicity call it 'getPhoneNumbers'.
Though I'm not entirely sure I understand what you asking, I think this may solve your issues:
for(int i = 0; i < contactos.size(); i++) {
Contacto next = contactos.get(i);
if(next.getEmails().contains(m)) {
next.display();
}
}
And as an afterthought, is there any specific reason you're only checking string containment? I would suggest that you check case-insensitive equality unless you really do want to find out if the string just contains the element.
Is this what you are looking for?
public class EmailSearcher {
Reader reader = new KeyboardReader();
public EmailSearcher(ArrayList<Contacto> contactos){
while(reader.read() != 'keyThatTerminates') {
String m = reader.read();
for(int i = 0; i<contactos.size();i++){
var row = contactos.get(i);
if(row.getEmails().contains(m)){
row.display();
}
}
}
}
}
I had a quick question, Right now I have a method that returns a populated DTO object, in another class I am calling that method, and then trying to get access to some of the values that are on the returned Object. I am having trouble figuring out what the syntax should be to accomplish this. It is returning "result". I am currently getting an error:
"Null pointer access: The variable result can only be null at this location"
The DTO that I am returning contains a List and I want to get access to one of the values on that list. Below is my code snippet. Thank you for your help!
for (Integer i = 0; i < array.size(); i++) {
// System.out.println(array.get(i));
GetAccountRewardSummaryRequest request = new GetAccountRewardSummaryRequest();
AccountRewardSummaryDTO result = null;
request.accountKey = new AccountIdDTO(array.get(i));
RewardServicesImpl rewardServicesImpl = new RewardServicesImpl();
rewardServicesImpl.getAccountRewardSummary(request);
// This will return an AccountRewardSummaryDTO, print out and see if it is returning properly
System.out.println(result.rewards.get(6));
// System.out.println(request.accountKey);
}
It's not clear from your question, but I suspect that this:
rewardServicesImpl.getAccountRewardSummary(request);
should be:
result = rewardServicesImpl.getAccountRewardSummary(request);
If you want to use the value returned from a method, you need to do something with it.
Your code would be clearer if you didn't declare the result variable until you needed it though - and there's no point in using Integer here instead of int. Additionally, unless you really can't reuse the service, you might as well create that once:
RewardServices service = new RewardServicesImpl();
for (int i = 0; i < array.size(); i++) {
GetAccountRewardSummaryRequest request = new GetAccountRewardSummaryRequest();
request.accountKey = new AccountIdDTO(array.get(i));
AccountRewardSummaryDTO result = service.getAccountRewardSummary(request);
System.out.println(result.rewards.get(6));
}
Also, as noted, the fact that your variable called array clearly isn't an array variable is confusing.
public void returnRental(Customer cust){
Rental toDelete = null; //Rental to be removed from list.
LinkedList<Video> toReturn = null; //List of videos to be added to inventory.
//Find appropriate rental according to customer name.
for(int i = 0; i < rentals.size(); i++){
if(cust.getName() == rentals.get(i).getRentee().getName()){
toReturn = rentals.get(i).getRented();
toDelete = rentals.get(i);
}
}
here is the snippet of code that is giving me problems. I've debugged it in eclipse quite a bit which ended up just confusing me more. It hits the if, and passes the condition. But once it gets to assigning values to "toReturn" it assigns it an empty list with size 0. Where as I check my rentals Linked list and the correct value are there, but for some reason it is not getting assigned to my variables correctly :( The same happens to "toDelete" but this isn't a list, it is one instance of my class Rental. (The linked list is a list of rentals, which contains a linked list of videos)
No errors are thrown...
Its a little difficult to explain, if you need more information please let me know and i'll clarify.
I'm at a loss, possibly because I'm not iterating through my linked list correctly?
Replace
if (cust.getName() == rentals.get(i).getRentee().getName()){
by
if (cust.getName().equals(rentals.get(i).getRentee().getName())){
You can't compare strings with == (except if your algorithm can ensure this is the same instance, which is almost never the case).
But the missing equals is not the only bug. It may be inside getRented() or elsewhere (you don't show what you do with toReturn and toDelete, so it's not clear if you don't have problems here).
Now, to go on chasing your bugs, you should either
debug, and put a breakpoint in your loop to check the state of rentals.get(i) and the execution at this point
if you can't debug, put a lot of System.println, so that you know what you have...
I've upvoted dystroy's answer because incorrect string comparison is always wrong.
But because that would fail differently (customer names not matching rentee names), I'm wondering if your issue is really caused by either of the following:
a problem in getRented(); or
cust having a null name on call, which would match a Rentee with a null name.
Possibly, your if condition is being hit more than once. First of all, check if this is actually happening. If so, check your logic and determine if you want to stop at the first occurence or at the last (this case seems to be the latter).
If you want to stop at the first occurence, break the iteration:
for(int i = 0; i < rentals.size(); i++){
if(cust.getName() == rentals.get(i).getRentee().getName()){
toReturn = rentals.get(i).getRented();
toDelete = rentals.get(i);
break;
}
}
for(int i = 0; i < rentals.size(); i++){
if(cust.getName().equals( rentals.get(i).getRentee().getName())){
toReturn.addAll(rentals.get(i).getRented());
//assumming it returns the list of Video object
toDelete = rentals.get(i);
}
}