如何使用模拟更改传递给方法的参数

How to change parameter passed to a method using mocking

假设类如下

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());
     }
}

现在我正在测试 Foo.storeThis(obj, time),为此,我需要添加不同的时间案例。我如何 change/mock 方法的参数? (考虑到我需要模拟 Foo.storeThis())。我怎样才能做到这一点? 我可以模拟一个方法,只改变它的参数并且实现与实际方法相同吗?

编辑:我不能直接调用Foo.storeThis(),因为我需要测试Bar.someOperation()的功能,我不能随机将obj放入Foo.storeThis()。

如果你想用不同的参数测试相同的方法,你可以很好地使用这些

`JUnitParamsRunner.class` and `@Parameters`

示例测试用例,

@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
    }
}

这样可以帮助您避免测试用例重复,并且您可以根据需要拥有尽可能多的测试输入。

如果您需要测试 obj 和 timeValue 的差异组合

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

并在参数中使用此方法。

//希望对您有所帮助..

解决方案:我得到了我需要的解决方案。事实证明,我可以使用模拟的 class 和 invocation.proceed() 方法来实现上述目标。这是一个代码示例(作为我所讨论示例的延续)。

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);
     }
}

在我的测试中 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
      }
}

谢谢