MatthiasDec
MatthiasDec

Reputation: 175

Test with Easymock for cases testing

I'm currently working on unit testing, and I'm trying to create a test testing different cases for a single function. For example, I have the following function:

public static String foo(Object arg0, Object arg1) {
    String returnValue = null;
    if(arg0.getName() != null && arg0.getId() != null) {
        returnValue = "Value 1";
    } else if (arg1.getName() != null && arg1.getId() != null ) {
        returnValue = "Value 2";
    }
    return returnValue;
}

I want to test the following cases :

etc...

My current test looks like this :

public void testFoo() {
    /** Setting up my mocks**/
    Obj arg0 = createMock(Obj.class);
    Obj arg1 = createMock(Obj.class);

    /** Setting my mocks behaviors **/

    // Case 1
    EasyMock.expect(arg0.getName()).andReturn(null);
    EasyMock.expect(arg1.getName()).andReturn(null);

    // Case 2
    EasyMock.expect(arg0.getName()).andReturn("Jack");
    EasyMock.expect(arg0.getId()).andReturn(1);
    EasyMock.expect(arg1.getName()).andReturn(null);

    // Case 3
    EasyMock.expect(arg0.getName()).andReturn(null);
    EasyMock.expect(arg1.getName()).andReturn("Paul");
    EasyMock.expect(arg1.getId()).andReturn(2);

    //End Cases
    EasyMock.replay(arg0_case1, arg0_case2, arg0_case3,

arg1_case1, arg1_case2, arg1_case3);

    /** Testing **/

    // Case 1
    String expectedValue = null;
    String output = foo(arg0, arg1);
    assertEquals(expectedValue, output);

    // Case 2
    expectedValue = "Value 1";
    output = foo(arg0, arg1);
    assertEquals(expectedValue, output);

    // Case 3
    expectedValue = "Value 2";
    output = foo(arg0, arg1);
    assertEquals(expectedValue, output);
}

The issue I have with this test is that even if I set up my mocks for each test case, it seems that the set up fails to follow the order I choosed. I tried to add a .once(), atLeastOnce(), but even with that, it fails.

Do you have any solutions for this kind of test ? Maybe I should write a different test for each case ?


EDIT I found a solution, thanks to @swayamraina's solution and some modification on my code. It's not the most efficient answer, but it does the job. Here's my edited code :

public void testFoo() {
/** Setting my mocks behaviors **/

// Case 1
Obj arg0_case1 = createMock(Obj.class);
Obj arg1_case1 = createMock(Obj.class);
EasyMock.expect(arg0_case1.getName()).andReturn(null).anyTimes();
EasyMock.expect(arg1_case1.getName()).andReturn(null).anyTimes();

// Case 2
Obj arg0_case2 = createMock(Obj.class);
Obj arg1_case2 = createMock(Obj.class);
EasyMock.expect(arg0_case2.getName()).andReturn("Jack").anyTimes();
EasyMock.expect(arg0_case2.getId()).andReturn(1).anyTimes();
EasyMock.expect(arg1_case2.getName()).andReturn(null).anyTimes();

// Case 3
Obj arg0_case3 = createMock(Obj.class);
Obj arg1_case3 = createMock(Obj.class);
EasyMock.expect(arg0_case3.getName()).andReturn(null).anyTimes();
EasyMock.expect(arg1_case3.getName()).andReturn("Paul").anyTimes();
EasyMock.expect(arg1_case3.getId()).andReturn(2).anyTimes();

//End Cases
EasyMock.replay(arg0, arg1);

/** Testing **/

// Case 1
String expectedValue = null;
String output = foo(arg0_case1, arg1_case1);
assertEquals(expectedValue, output);

// Case 2
expectedValue = "Value 1";
output = foo(arg0_case2, arg1_case2);
assertEquals(expectedValue, output);

// Case 3
expectedValue = "Value 2";
output = foo(arg0_case3, arg1_case3);
assertEquals(expectedValue, output);

Like @swayamraina proposed in its answer, I created different mocks for each case test, and I add a .anyTimes() after each EasyMock.expect().andReturn(), and it works well. I'll keep this post update on improvements I may implement.

Upvotes: 0

Views: 498

Answers (1)

swayamraina
swayamraina

Reputation: 3158

Below is the updated test case

@Test
public void test()  {

  A arg0, arg1;

  // Case 1
  arg0 = EasyMock.createMock(A.class);
  arg1 = EasyMock.createMock(A.class);

  // expectations
  EasyMock.expect(arg0.getName()).andReturn(null).once();
  EasyMock.expect(arg1.getName()).andReturn(null).once();
  EasyMock.replay(arg0, arg1);

  // actuals
  String expectedValue = null;
  String output = foo(arg0, arg1);

  // assertions
  Assert.assertEquals(expectedValue, output);


  // Case 2
  arg0 = EasyMock.createMock(A.class);
  arg1 = EasyMock.createMock(A.class);

  // expectations
  EasyMock.expect(arg0.getName()).andReturn("Jack").once();
  EasyMock.expect(arg0.getId()).andReturn(1).once();
  EasyMock.expect(arg1.getName()).andReturn(null).once();
  EasyMock.replay(arg0, arg1);

  // actuals
  expectedValue = "Value 1";
  output = foo(arg0, arg1);

  // assertions
  Assert.assertEquals(expectedValue, output);


  // Case 3
  arg0 = EasyMock.createMock(A.class);
  arg1 = EasyMock.createMock(A.class);

  // expectations
  EasyMock.expect(arg0.getName()).andReturn(null).once();
  EasyMock.expect(arg1.getName()).andReturn("Paul").once();
  EasyMock.expect(arg1.getId()).andReturn(2).once();
  EasyMock.replay(arg0, arg1);

  // actuals
  expectedValue = "Value 2";
  output = foo(arg0, arg1);

  // assertions
  Assert.assertEquals(expectedValue, output);
}



Test class used:

class A {
    String name; public String getName() {return  name;} 
    Integer id; public Integer getId(){return id;}
}


Notes:
You can only replay the mocks only once. You need to create new test objects for every test case. Here, we are first creating mocks then setting expectations and replaying the mocks. Finally asserting against the actual values.


As a general process, I like to create 1 test function per unit (actual function) with . multiple test cases describing each.
Also each test case follows the below pattern

  1. declare variables
  2. describe test case
  3. set expectations
  4. define result (actual)
  5. apply assertions

Upvotes: 1

Related Questions