简体   繁体   English

在带参数的测试中找不到JUnit测试

[英]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 . 我刚刚学习了JUnit测试,并且我已经获得了使用参数进行测试的示例,所以我正在应用这个以及Daniel Mayer的Our CraftMkyong等网站的文档和示例。

I'm asked to test the fill() method with a parameterized class. 我被要求用参数化类测试fill()方法。 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: 但现在这是我带参数的测试类(想法是测试fill()方法:

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). 我做了很多修改以适应示例,但是大多数都不考虑另一个测试类(我需要按照指示最终创建一个JUnit测试套件)。 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. 在考虑作为一个菜鸟问题之前,请求我任何你需要的东西,我已经完成了所有的研究,但我相信例子不符合我的问题,或者我可能不知道应该看到差异。

You are declaring that your test class should be used as @RunWith(Parameterized.class) 您声明您的测试类应该用作@RunWith(Parameterized.class)

That implies that it provides a method that carries the @Parameters annotation. 这意味着它提供了一个带有@Parameters注释的方法。

Thus: add this annotation to your method fillAmounts() and you should be good. 因此:将此注释添加到方法fillAmounts() ,您应该很好。

The error message is basically telling you that the runner can't find the method it needs in order to do its job. 错误消息基本上告诉您,运行器无法找到执行其工作所需的方法。

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 @Parameters line. 与问题代码相比,第3部分缺少@Parameters行。 Also, the assertTrue() line in Part 4 was wrong, since tank.fill(amount); 另外,第4部分中的tank.fill(amount); )行是错误的,因为tank.fill(amount); already added "amount" to TankLevel. 已经向TankLevel添加了“金额”。

For purposes of the course,I used assertEquals instead of assertTrue (which had me looking for the meaning of "delta"). 出于本课程的目的,我使用assertEquals而不是assertTrue(我让我寻找“delta”的含义)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM