Testing a method with return type void

37,443

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:

  1. Creating an ArrayList arr;
  2. Adding some things to it;
  3. Invoking arr.clear();
  4. 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.

Share:
37,443
Evgenij Reznik
Author by

Evgenij Reznik

Updated on September 20, 2020

Comments

  • Evgenij Reznik
    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
      azurefrog over 9 years
      Sure you can. It looks like methodA() is modifying the internal state of an ArrayList, so you can make your test class check the contents of the list before and after executing the method.
    • StackFlowed
      StackFlowed over 9 years
      Yes 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
      nbro over 9 years
      Of 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
      Joe over 9 years
  • chiastic-security
    chiastic-security over 9 years
    Would 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
    Sergey Kalinichenko over 9 years
    @chiastic-security That is a fair observation, thank you very much!
  • Evgenij Reznik
    Evgenij Reznik over 9 years
    What 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
    chiastic-security over 9 years
    Well, 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
    Evgenij Reznik over 9 years
    Should 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
    rgettman over 9 years
    How is this data being used? If it's being used by other methods such as methodB, then you can use methodB and test its side effects.
  • Jeff Bowman
    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.