如何使用 powermock 捕获函数输入?
How do I trap a function inputs using powermock?
假设我有如下测试功能:
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)
}
你应该不需要这样做!
假设 context 是您封闭的 class 的 field,那么您 "simply" 必须找到一种为您的 class 测试中的 mocked 对象提供 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(...
使用上述方法,您对 Power 模拟的整个需求就消失了。您可以使用 "ordinary" 模拟框架,例如 Mokito 或 EasyMock 来 prepare/verify 您的上下文对象!
你看,最后,你的问题是你创建的代码只是难以测试,除非你开始考虑依赖注入。如果您认真对待测试,请观看这些 videos;他们向您广泛介绍了如何实际创建可测试代码。
这是我自己制定的解决方案,并且可以根据需要完美运行。在没有 mrunit 帮助的情况下,我也使用这种技术有效地测试了我所有的 map-reduce 代码。
@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 ));
}
假设我有如下测试功能:
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)
}
你应该不需要这样做!
假设 context 是您封闭的 class 的 field,那么您 "simply" 必须找到一种为您的 class 测试中的 mocked 对象提供 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(...
使用上述方法,您对 Power 模拟的整个需求就消失了。您可以使用 "ordinary" 模拟框架,例如 Mokito 或 EasyMock 来 prepare/verify 您的上下文对象!
你看,最后,你的问题是你创建的代码只是难以测试,除非你开始考虑依赖注入。如果您认真对待测试,请观看这些 videos;他们向您广泛介绍了如何实际创建可测试代码。
这是我自己制定的解决方案,并且可以根据需要完美运行。在没有 mrunit 帮助的情况下,我也使用这种技术有效地测试了我所有的 map-reduce 代码。
@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 ));
}