WR10
WR10

Reputation: 31

Writing junit test for a method returning object

I am new to writing junit tests. I am stuck at how to write tests for methods returning object. I went through this question, but I am not convinced. I can't make changes to the method. I want to write a test for this method:

public final class Demo{
      public Test getTestObject() {
            return this.testObject== null ? Test.getDefaultInstance() : this.testObject;
        }
}

Test Class:
public final Test{
private Test()
{
}
}

Thanks for your help.

Upvotes: 3

Views: 10568

Answers (2)

davidxxx
davidxxx

Reputation: 131326

You have two branches to test :

  • the testObject field references a not null object, so it is returned
  • the testObject field references null, so you create it from the getDefaultInstance() method.

So you could define two test methods to test each scenario and assert that the expected Test instance is returned.

Note that generally you should not override equals()/hashCode() only to make a unit test working.
Actually if Test.getDefaultInstance() returns at each time the same instance. You just need to compare two Test object references.
Assert.assertSame(Object o1, Object o2) of JUnit allowing to assert that o1==o2 is so enough :

Supposing that the class to test is Foo :

@Test
public void getTestObject_as_null(){
   Foo foo = new Foo();
   Assert.assertSame(Test.getDefaultInstance(), foo.getTestObject());
}

@Test
public void getTestObject_as_not_null(){
   Foo foo = new Foo();
   Test test = new Test(...);
   foo.setTestObject(test);
   Assert.assertSame(test, foo.getTestObject());
}

It could also work with Assert.assertEquals() but Assert.assertSame() conveys better the intention of what we want to assert : the references.

On the contrary if Test.getDefaultInstance() returns different instances at each invocation, you should compare the content of the returned Test instances.
The test could look like :

@Test
public void getTestObject_as_null(){
   Foo foo = new Foo();
   Test expectedTest = Test.getDefaultInstance();
   Test actualTest = foo.getTestObject();
   Assert.assertEquals(expectedTest.getX(), actualTest.getX());
   Assert.assertEquals(expectedTest.getY(), actualTest.getY());
}

And that test don't need to change as the object referenced by getTestObject() and the expected Test object is necessary the same as you pass it as fixture :

@Test
public void getTestObject_as_not_null(){
   Foo foo = new Foo();
   Test test = new Test(...);
   foo.setTestObject(test);
   Assert.assertSame(test, foo.getTestObject());
}

Upvotes: 1

pavithraCS
pavithraCS

Reputation: 691

You can implement a good equals method for your Test object and use it within your unit test. I have written a sample code.

public class Foo
{

  int a = 0;
  int b = 0;
  String c = "";

  public Foo(int a, int b, String c)
  {
    this.a = a;
    this.b = b;
    this.c = c;
  }

  public static Foo getDefaultInstance()
  {
    return new Foo(1, 1, "test");
  }

  @Override
  public boolean equals(Object o){
    if (o == this) return true;
    if (!(o instanceof Foo)) {
        return false;
    }

    Foo foo = (Foo) o;

    return foo.a== a &&
        foo.b == b &&
            foo.c.equalsIgnoreCase(c);
  }

  @Override
  public int hashCode() {
      int result = 17;
      result = 31 * result + a;
      result = 31 * result + b;
      result = 31 * result + c.hashCode();
      return result;
  }

}

This class contains the method that we need to test.

public class Other
{
  Foo foo;

  public Foo getFoo()
  {
    return this.foo == null ? Foo.getDefaultInstance() : this.foo;
  }

}

This is the class with test method.

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

public class MyTest
{
  @Test
  public void testGetFoo() {
     Other other = new Other();
     Foo foo = other.getFoo();
     assertEquals(foo, new Foo(1, 1, "test"));

  }
}

Upvotes: 1

Related Questions