Aravind Shankar
Aravind Shankar

Reputation: 53

How to change parameter passed to a method using mocking

Imagine classes as below

public class Foo {

     public void storeThis(Object obj, long storeTime){
           //store the obj with storeTime
     }
}

public class Bar {
     public void someOperation(){
           //doSomething
           BarUtils.storeMe(obj);
     }
}

public class BarUtils {
     Foo _f = new Foo();
     static void storeMe(Object obj){
          //doSomething
          _f.storeThis(obj, System.currentmillis());
     }
}

Now I am testing the Foo.storeThis(obj, time), for that, I need to add different time cases. How can I change/mock the parameter of a method? (Considering I need to mock Foo.storeThis()). How can I achieve this? Can I mock a method so that only its parameter is changed and the implementation is the same as the actual method?

Edit: I cannot directly invoke Foo.storeThis(), Since I need to test the functionality of Bar.someOperation() and I cannot randomly put obj into Foo.storeThis().

Upvotes: 0

Views: 1626

Answers (2)

Aravind Shankar
Aravind Shankar

Reputation: 53

Solution: I got the solution for what I needed. It turns out that I can use a mocked class and an invocation.proceed() method to achieve the above. Here is a code example (as a continuation of my example in question).

public class FooMock extends MockUp<Foo> {
   private long newStoreTime;

   public void setTimeToBeMocked(long storeTime) {
      newStoreTime = storeTime;
   }
   public void storeThis(Invocation inv, Object obj, long storeTime){
           inv.proceed(obj, newStoreTime);
     }
}

In my test class :


public class BarTest {
      @Test
      public void testSomeOperation(long testInTime){
          FooMock mock = new FooMock();
          Bar bar = new Bar();
          mock.setTimeToBeMocked(testInTime);
          bar.someOperation();//This would store obj in testInTime
      }
}

Thanks

Upvotes: 1

Sabareesh Muralidharan
Sabareesh Muralidharan

Reputation: 647

If you wanted to test same method with different parameters, you can very well use these

`JUnitParamsRunner.class` and `@Parameters`

A sample testcase,

@RunWith (JUnitParamsRunner.class)
public class TestFoo
{
    public Object[] storeTimeValues()
    {
        return new Object[] {
                              LONG_VALUE_1,
                              LONG_VALUE_2, ...
        };
    }
    
    @Test
    @Parameters (method = "storeTimeValues")
    public void testStoreThisWithDifferentTimeValues(long timeValue)
    {
        Foo foo = new Foo();
        foo.storeThis(custom_object, timeValue);
        get the time from the obj and assert it against longValue
    }
}

This way it would help you to avoid test case duplication and you can have as many test inputs as you need.

If you need to test diff combinations of obj and timeValue

public Object[][] getDiffValues()
{
    return new Object[][] {
                         new Object[] { CUSTOM_OBJECT_1, LONG_VALUE_1 },
                         new Object[] { CUSTOM_OBJECT_1, LONG_VALUE_2 }
    };
}

and use this method within parameter.

//Hope it helps..

Upvotes: 0

Related Questions