简体   繁体   中英

Why does my function keep failing my JUnit test?

This is one of my classes that I am testing. It keeps failing the calculateVolume() method and I am not sure why.

   package shape3D;


public class Sphere implements Cloneable {
    private double myRadius;
    private double myVolume;
    private double mySurfaceArea;
    private final static double pi = 3.14;

    public static void main(String args[]){
        Sphere sphere = new Sphere();
    }
    public double calculateVolume(){
        myVolume = (4/3)*pi*(Math.pow(myRadius,3));
        return myVolume;
    }
     public double calculateSurfaceArea(){
         mySurfaceArea = ((4)*(pi)*(Math.pow(myRadius,2)));
         return mySurfaceArea;
     }
     public double getSurfaceArea(){
         return this.calculateSurfaceArea();
     }
     public double getVolume(){
         return this.calculateVolume();
     }
     public void setRadius(double radius2){
         myRadius = radius2;
     }

     public String toString(){
            return "Volume: " + this.getVolume() + "   Surface area " + this.getSurfaceArea();
        }
     public Sphere clone (){
            Sphere p = new Sphere();
            p.setRadius(myRadius);
            return p;
        }

}

Here is the JUnit test case I am using

public class sphereTest {
    @Test
    public void testSphere(){
        shape3D.Sphere sphere = new shape3D.Sphere();
        sphere.setRadius(6);
        assertTrue(sphere.calculateSurfaceArea()== 452.16);
        assertTrue(sphere.calculateVolume()== 904.32);

The calculateSurfaceArea() stuff passes fine but the volume is failing and I am not sure why.

You're doing integer division when calculating the volume truncating the first term of the equation to 1 . Replace

myVolume = (4 / 3) * pi * (Math.pow(myRadius, 3)); // 678.24

with

myVolume = (4 / 3.0) * pi * (Math.pow(myRadius, 3)); // 904.31

Due to floating point imprecision you will still need to allow for the difference between the expected & calculated values. You can use this version of assertEquals which allows a delta value to do the comparison - replace

assertTrue(sphere.calculateVolume()== 904.32);

with

assertEquals(sphere.calculateVolume(), 904.32, .02);

The calculation

myVolume = (4/3)*pi*(Math.pow(myRadius,3));

Uses integer arithmetic: 4/3 evaluates to 1 .

Change it to

myVolume = (4.0/3)*pi*(Math.pow(myRadius,3));

Quite aside from the 4/3 integer problem (which I failed to spot): It's not safe to compare two Java double values this way.

If you use assertEquals instead of assertTrue then you might see the problem. I'm betting that it's calculating 4/3 first, then truncating it. And it'll still do this even if you make those into doubles.

Use the overload for assertEquals as mentioned in this question .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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