Nooblhu
Nooblhu

Reputation: 572

No JUnit test found in test with parameters

I'm just learning JUnit testing and I have been given examples of testing with parameters so I'm applying this and the documentation and examples of sites like Daniel Mayer's Our Craft and Mkyong.

I'm asked to test the fill() method with a parameterized class. This is the original class:

package FuelTankTestPractice;

/**
 * FuelTank is the class which represents the fuel tank of a car.
 * A FuelTank object encapsulates the state information needed for describing the state of the tank:
 * <ul>
 *   <li> tankMax   capacity of the tank
 *   <li> tankLevel fuel level of the tank
 * </ul>
 * 
 * class invariant      0.0 &lt;= tankLevel &lt;= tankMax
 * 
 * @author UC3M MOOC Team
 *
 */
public class FuelTank {

    private double tankMax;
    private double tankLevel;

   /**
    * FuelTank is a constructor of the class. 
    * 
    * <hr>
    * <br> precondition  tankMax &gt; 0.0 and 0.0 &lt;= tankLevel &lt;= getTankMax()  
    * <br> postcondition tankMax &gt; 0.0 and 0.0 &lt;= tankLevel &lt;= getTankMax() 
    * <hr>
    * 
    * @param tankMax  is the amount of fuel  (measured in liters) that the tank can hold
    * @param tankLevel is the amount of fuel (measured in liters) that the tank will have initially
    * 
    */ 
    FuelTank(double tankMax, double tankLevel) {
       this.tankMax   = tankMax;
       this.tankLevel = tankLevel;
    }

   /**
    * getTankLevel is an accessor method
    * 
    * @return   the amount of fuel in the tank
    */
    public double getTankLevel(){
       return tankLevel;
    }

   /**
    * getTankMax is an accessor method
    * 
    * @return   the capacity (in liters) of the tank
    */
    public double getTankMax(){
       return tankMax;
    }

   /**
    * isEmpty gives a status report 
    * 
    * @return   <code>true</code> if the tank is empty 
    *          <code>false</code> otherwise.
    */
    public boolean isEmpty(){
      return tankLevel == 0;
    }

    /**
     * isFull gives a status report 
     * 
     * @return  <code>true</code> if the tank is full 
     *          <code>false</code> otherwise.
     */
    public boolean isFull(){
      return tankLevel == tankMax;
    }

   /**
    * fill is a mutator method that adds fuel to the tank
    * 
    * <hr>
    * <br> precondition     0.0 &lt; amount &lt;= getTankMax() - getTankLevel() 
    * <br> postcondition    not empty
    * <br> postcondition    tankLevel &gt; tankLevel_initial 
    * <hr>
    * 
    * @param amount     the quantity of fuel to add
    * 
    */
    public void fill(double amount){
       tankLevel = tankLevel + amount;
    }

   /**
    * consume is a mutator that consumes amount of fuel
    * 
    * @param amount the amount of fuel to consume
    * 
    */
    public void consume(double amount){
       tankLevel = tankLevel - amount;
    }
}

First I had to create a simple test class, that worked without problems:

package FuelTankTestPractice;

/**
 * Tests for class FuelTank.
 * 
 * All tests in the folder "test" are executed 
 * when the "Test" action is invoked.
 * 
 */

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.Before;

public class FuelTankTest {

    FuelTank tank = null;

    @Before
    public void setUp() throws Exception {
    tank = new FuelTank(60.0,10.0);
    }

    @Test
    public void testGetTankLevel() {
    tank.getTankLevel();
    assertTrue(tank.getTankLevel()==0.0);
    }

    @Test
    public void testGetTankMax() {
    tank.getTankMax();
    assertTrue(tank.getTankMax()==60.0);
    }

    @Test
    public void testIsEmpty() {
    tank.isEmpty();
    assertTrue(!tank.isEmpty());
    }

    @Test
    public void testHalfFullTank() {
    assertTrue(tank.getTankMax()/2==30.0);
    }

 }

But now this is my test class with parameters (the idea is to test the fill() method:

package FuelTankTestPractice;

import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class FillingTest extends FuelTankTest{
private double amount;
private double result;

//constructor
public FillingTest (double amount, double result) {
this.amount = amount;
this.result = result;
}

FuelTank tank = new FuelTank(60, 10);

//Declares parameters here
public static Collection<Object[]> fillAmounts(){ 
    Object[][] amounts = new Object[][]{
        {10.0,20.0},
        {15.0,35.0},
        {20.0,30.0},
        {35.0,45.0}}; 
return Arrays.asList(amounts); 
}

@Test   
public void TestFill() {
tank.fill(amount);
assertTrue(amount + tank.getTankLevel() == result);
    }
}

The main class and method is pretty simple but I'll add it if it helps:

public class Main {

public static void main(String[] args) {

    // create the tank
    FuelTank tank = new FuelTank(40.0,0.0);

    System.out.print("The tank with capacity " + tank.getTankMax() + " liters has been created. ");
    System.out.println(" Its initial fuel level is  " + tank.getTankLevel() + " liters.");
}
}

I've made many changes to fit with examples, but most of them dont consider another test class (which I require to create a JUnit Test Suite in the end, as instructed). Sometimes it throws:

java.lang.Exception: No public static parameters method on class FuelTankTestPractice.FillingTest
    at org.junit.runners.Parameterized.getParametersMethod(Parameterized.java:299)
    at org.junit.runners.Parameterized.<init>(Parameterized.java:246)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:84)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

I Hope all this info helps. It's not about to solve my "homework" but about learning. Pleas ask me anything you need before consider as a noob question, I've done all the research I can but I believe examples dont match my question, or maybe I dont know enought to see the difference.

Upvotes: 4

Views: 3139

Answers (2)

Nooblhu
Nooblhu

Reputation: 572

This is the final working code that passed the test:

package FuelTankTestPractice;

import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

//Part 1: Runwith
@RunWith(Parameterized.class)
public class FillingTest {

    private double amount;
    private double result;

    //Part 2: Constructor
    public FillingTest (double amount, double result) {
        this.amount = amount;
        this.result = result;
    }

    //Part 3: Declares parameters here
    @Parameters
    public static Collection<Object[]> fillAmounts(){ 
        Object[][] amounts = new Object[][]{
            {10.0,20.0},
            {15.0,25.0},
            {20.0,30.0},
            {35.0,45.0}}; 
        return Arrays.asList(amounts);
    }

    // Part 4: Test method
    FuelTank tank = new FuelTank(60.0,10.0);    

    @Test
    public void TestFill() {
        tank.fill(amount);
        assertEquals(result, tank.getTankLevel(), 0.0001); 
        // Or assertTrue(tank.getTankLevel() == result);
    }
}

Compared to the question code, Part 3 lacks the @Parametersline. Also, the assertTrue() line in Part 4 was wrong, since tank.fill(amount); already added "amount" to TankLevel.

For purposes of the course,I used assertEquals instead of assertTrue (which had me looking for the meaning of "delta").

Upvotes: 1

GhostCat
GhostCat

Reputation: 140613

You are declaring that your test class should be used as @RunWith(Parameterized.class)

That implies that it provides a method that carries the@Parameters annotation.

Thus: add this annotation to your method fillAmounts() and you should be good.

The error message is basically telling you that the runner can't find the method it needs in order to do its job.

Upvotes: 4

Related Questions