Testing a method with return type void
Solution 1
It is possible to test methods that don't return anything (void
), but you must test that method's side effects. It should have some side effects, otherwise such a method is useless.
The side effect here is that al
is changed. As written, this class doesn't have any other methods that expose al
. Add a getter method that returns either the ArrayList
or a specific element of the ArrayList
. Then your test method can call the getter method to retrieve the value(s) and compare it(them) with the expected value(s).
Solution 2
Yes, certainly you can test a method with no parameters.
It may be that an example is the best way of seeing this. Think about the ArrayList.clear()
method. What it does is to empty the ArrayList
, so that its size is then zero. You'd test this method by:
- Creating an
ArrayList arr
; - Adding some things to it;
- Invoking
arr.clear()
; - Checking
assertEquals(arr.size(),0)
.
In other words, you're setting things up so that your ArrayList
has a state you don't want (size()>0
); then you're invoking the method that should have a predictable effect on the state (setting size()
to 0
); then checking that the effect is as you expected.
Solution 3
Methods without parameters are used for their return value or for their side effects. Therefore, testing of these methods consists of these three steps:
- Set the object being tested to the initial state before calling the parameterless method
- Call the parameterless method
- Check the return value or the side effects of the parameterless method
The last step can check either the new state of the object being tested, or the results of its work in the overall environment of the system.
Here is a small example:
class Calculator {
private int left, right, result;
public void setLeft(int val) { left = val; }
public void setRight(int val) { right = val; }
public int getResult() { return result; }
public void add() { result = left + right; }
public void multiply() { result = left * right; }
}
You could test its multiply()
method like this:
@Test
public void testMultiply() {
// Set the object being tested to the initial state
Calculator tester = new Calculator();
tester.setLeft(5);
tester.setRight(10);
// Call the method
tester.multiply();
// Check the new state
assertEquals("10 x 5 must be 50", 50, tester.getResult());
}
This sample tests side effects of the method. Testing a method with a return value and no side effects would combine the call of the method with its check on the assertion line.
Solution 4
Yes you can test these method if you are using these method in other methods as a side effects. As for example-
public class test{
public int i=0;
public void incrementIngeterValue()
{
//doing something and
i++;
}
public boolean incremented()
{
//some logic to check what is current i value
int x = incrementIngeterValue();
if(x==i)
return false; // value not incremented
else
return true // in this case you can make sure this value is incremented by 1.
}
So you can test incremented method for checking i value is incremented by 1 or not, with this method you are internally test your incrementIngeterValue() without parameter and return value.
In your case you a1 is effected in both methods. somewhere you are using this a1.
Evgenij Reznik
Updated on September 20, 2020Comments
-
Evgenij Reznik over 3 years
I'm new to software testing. In a tutorial I read that I can test some methods like this:
@Test public void testMultiply() { MyClass tester = new MyClass(); assertEquals("10 x 5 must be 50", 50, tester.multiply(10, 5)); }
So I have to pass some parameters to a method and get a return value.
But in my case I have some classes without any parameters and return values:ArrayList al = new ArrayList(); public void Main(){ methodA(); methodB(); } public void methodA(){ // connect to URL // get some data for(int i=0; i<someThing; i++){ al.add(data); } } public void methodB(){ // do something with al }
Is it also possible to test them? For example whether the right value comes from the URL in
methodA()
.-
azurefrog over 9 yearsSure you can. It looks like
methodA()
is modifying the internal state of anArrayList
, so you can make your test class check the contents of the list before and after executing the method. -
StackFlowed over 9 yearsYes it is depending on what is important in that you can use mockito to verify if a implementation was called or you can verify the object that it mutates.
-
nbro over 9 yearsOf course. Usually, if no error occurs during the call to the function without no parameters and return value, it means that the function could work. Of course, it's not true at all. For this purpose, you could simply use the debugger and test the flow of the program.
-
Joe over 9 yearspossible duplicate of How to test void method with Junit testing tools?
-
-
chiastic-security over 9 yearsWould be worth clarifying: methods without parameters or a return value are used for their side effects. Methods without parameters, but with a return value, needn't have side effects (e.g., getter methods).
-
Sergey Kalinichenko over 9 years@chiastic-security That is a fair observation, thank you very much!
-
Evgenij Reznik over 9 yearsWhat if you wouldn't actually need the method size() in my implementation? Should I create it so that the testing class can use it?
-
chiastic-security over 9 yearsWell, the point is that the method being tested must have some effect on the state, and that change in state must be detectable with the methods you've got already... or else either the method is pointless, or you need some more methods! In other words, if you don't have any methods that act differently depending on whether you've cleared the
ArrayList
, there would never be any point in clearing it. -
Evgenij Reznik over 9 yearsShould I add this method only so that the test class can call it? Even if I don't actually need it in my code?
-
rgettman over 9 yearsHow is this data being used? If it's being used by other methods such as
methodB
, then you can usemethodB
and test its side effects. -
Jeff Bowman over 9 years@user1170330 Yes. You're writing a testable component, and that means writing enough accessors that you can test it. If these shouldn't be called in production, document them as such.