如何使用powermock捕获函数输入?

7cwmlq89  于 2021-06-10  发布在  Hbase
关注(0)|答案(2)|浏览(412)

假设我要测试的函数如下:

boolean MyFunction (String input1, Text rowkey) {
   int a = 10;
   a = a + 10;
   return context.write(rowkey,a);
}

请注意,context.write是一个向数据库写入数据的函数。
我想模拟这个函数并检查传递给它的输入是否正确。我该怎么做?
基本上,我能做如下的事情吗(我似乎无法工作):

PowerMockito.when(Context.write((Text) anyObject(),
  (int) anyObject())).then(compareResult(input1,input2));

 private Answer<Boolean> compareResults(input1, input2) {
     AssertTrue(input1,this.Test1Input1AcceptanceCriteria)
     AssertTrue(input2,this.Test1Input2AcceptanceCriteria)
 }
6kkfgxo0

6kkfgxo01#

这是我的解决方案,我自己制定,并完美地工作,因为我需要它。我用这种技术有效地测试了我所有的map reduce代码,而不需要mrunit的帮助。

@Test
public void testMyFunction () throws Exception {
   Context testContext = mock(Context.class);
   MyFunction (input1, rowkey); // Call the function under test
   // Now here is the magic. We use the verify technique to test 
   // the mocked class method while checking for equality with the acceptance criteria.
   // In essence, the key is trap these underlying functions and ensure that
   // they are passed in the right input from your function under test.
   int expected_input_to_write = 10
   Mockito.verify(testContext).write(eq((Object) new Text("test_string")), eq((Object) expected_input_to_write )); 
}
sh7euo9m

sh7euo9m2#

你不应该这样做!
假设context是封闭类的一个字段,那么您必须“简单地”找到一种方法,向测试中的类提供此类context对象的模拟版本。
这里的典型方法是:依赖注入
比如:

public class Foo {
   private final Context context;

   // some external constructor that you would use to create Foo objects
   public Foo() { this (new Context(...)); }

   // an internall ctor, used by your unit tests
   Foo(Context context) { this.context = context;  }

然后,您可以编写单元测试,例如

@Test
public void testMyFunction() {
  Context context = ... create some mock
  Foo underTest = new Foo(context);
  underTest.myFunction(...

使用上面的方法,你对权力嘲弄的需求就消失了。您可以使用“普通”模拟框架(如mokito或easymock)来准备/验证您的上下文对象!
你看,最后,你的问题是你创建的代码很难测试,除非你开始考虑依赖注入。如果你是认真的测试,看这些视频;它们为您提供了如何实际创建可测试代码的广泛介绍。

相关问题