修改字节代码以使方法返回true

时间:2011-05-29 06:07:27

标签: classloader bytecode bytecode-manipulation java-compiler-api

我的类文件有这样的方法:

public boolean validate(String str) {}

这个验证方法中有很多代码,但我只想让它总是返回true或false。有人能指出我如何修改类文件来实现这个目标吗?

4 个答案:

答案 0 :(得分:5)

RULE覆盖rtn CLASS Foo 方法验证 如果是真的 DO RETURN是真的 ENDRULE

http://www.jboss.org/byteman

答案 1 :(得分:2)

您是否正在尝试对此代码进行单元测试并在不关心条件的情况下强制执行答案?如果是这种情况,那么您正在寻找“模拟”框架。在Java中,我可以想到MockitoEasyMock

相关地,您可以使用PowerMock(与上述任一Mocking框架协同工作)动态更改类(例如final类/方法,static方法,甚至private个课程。 PowerMock实际上可以在必要时更改字节代码。检查其类加载文件夹。

我从来没有考虑过它,但可能在非测试代码中使用它们中的任何一个,但是它们可能需要进行处理才能避免JUnit依赖(例如JUnit Runner)。我再也没想过,所以我从未想过这些含义。

至少,您可以查看PowerMockito以了解它们如何更改字节代码。

如果您只想进行单元测试,那么它非常简单,您可能不需要担心字节码。

public class SomeClass {
    public boolean validate(String s) {
        // tons of logic
    }
}

测试(使用Mockito和JUnit 4(删除JUnit 3的@Test属性)):

private final MyClassBeingTested testClass = new MyClassBeingTested();

@Test
public void testMyCodeWithSomeClass() {
    SomeClass some = mock(SomeClass.class);

    when(some.validate(anyString())).thenReturn(eq(true));

    // whenever it uses "some.validate()", with any
    //  string, then it will return true
    testClass.useSomeClass(some);

    // assert whatever conditions you want

    // if you care to ensure that it called validate:
    //  note: times(1) is implied if not supplied, but times(0), times(2), etc.
    //  could be used ("never()" exists as a synonym for times(0))
    verify(some, times(1)).validate(anyString());
}

答案 2 :(得分:1)

根据提供的方法签名,它只能返回true或false 你能创建一个包装类来委托对原始的调用并覆盖你需要的行为,而不是试图操纵字节码吗?

答案 3 :(得分:1)

修改字节代码的最简单方法是对类进行反编译或获取源代码的副本。更改代码并编译它。将新版本放在类路径中,或者替换jar中的原始版本。这样你就改变了方法。

您可以在运行时更改它,但这比100倍更难。 ;)