Alex Rainbird
Alex Rainbird

Reputation: 1

JUnit test on getter method not working

I am working on a Java exercise in Eclipse to add JUnit tests to a existing project. This isn't for an assignment or anything, just a way to get used to Eclipse (I had been using BlueJ previously). However, the two test methods I have written don't seem to be working. For some reasons, the Circle objects I have created (which have a radius field, which I have set as 6, 8 and 2 to three different circles) keep defaulting to a radius of 0, so both of my test methods (one does actually report to work, but this is because it is checking the circumference is >= 0) fail. What have I done wrong? I am not an experienced programmer so the mistake may be obvious to most of you.

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


public class CircleTest {
    Circle circle1;
    Circle circle2;
    Circle circle3;
@Before
public void setUp() throws Exception {

    circle1 = new Circle(6.00);
    circle2 = new Circle(8.00);
    circle3 = new Circle(2.00);
}




@Test
public void testCircumference() {
    assertTrue(circle1.circumference() >= 0);
    assertTrue(circle2.circumference() >= 0);
    assertTrue(circle3.circumference() >= 0);

}

@Test
public void testGetter() {
    assertEquals(6, circle1.getRadius(), 1e-15);
    assertEquals(8, circle2.getRadius(), 1e-15);
    assertEquals(2, circle3.getRadius(), 1e-15);

}

@After
public void tearDown() throws Exception {
}

}

Upvotes: 0

Views: 1050

Answers (4)

Eric Jablow
Eric Jablow

Reputation: 7899

The error must be in the Circle class. Your tests, though they have some minor flaws, seem okay.

  1. Since you are using JUnit 4 annotations, you need not name your @Before method setUp.
  2. You down't need a tearDown method, since it is empty. You also don't need to name it tearDown.
  3. These classes should have but one assert, Were something wrong with circle1, you'll never test circle2 and circle3. In fact, you should look up parameterized JUnit tests.

So, what should your Circle class look like? Here's an idea, and some hooks for test writing.

public class Circle implements Serializable {
    private static long serialVersionUid = ...;

    private final double radius;

    public Circle(final double radius) throws IllegalArgumentException {
        if (radius <= 0.0) {
            throw new IllegalArgumentException("Attempt to create a circle with nonpositive radius" + radius);
        }
        this.radius = radius;
    }
    public double getRadius() {...}
    public double getCircumference{...}
}

Now, test that:

  1. new Circle(-10.0) throws.
  2. new Circle(Double.NaN) throws,
  3. new Circle(10.0) succeeds.
  4. (new Circle(10.0)).getRadius() returns 10.
  5. (new Circle(10.0)).getCircumference() returns approximately 31.4159.
  6. Circle implements Serializable.

Upvotes: 0

Reimeus
Reimeus

Reputation: 159874

More than likely the value returned by getRadius is the default value of 0.0 for double primitive types

Ensure the radius is assigned in the constructor of Circle

public Circle(double radius) {
    this.radius = radius;
}

so that the value can be returned by getRadius

public double getRadius() {
   return radius;
}

Upvotes: 1

Thomas
Thomas

Reputation: 12049

I assume that you use dobules or floats for the radius. Working with these types can be tricky, since they are not precise. Unit test frameworks provide special comparison methods for this case:

http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals%28double,%20double,%20double%29

So you would use for example

 assertEquals(6, circle1.getRadius(), 0.0001);

Upvotes: 0

popfalushi
popfalushi

Reputation: 1362

Take a look: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
In 2 words: floating points should not be compared by equals - you should compare them by their absolute difference: a - b < 0.00001, for example.
I think, it is a root of a problem here.

Upvotes: 0

Related Questions