1

クラスファイルには次のようなメソッドがあります:

public boolean validate(String str) {}

この検証メソッド内には多くのコードがありますが、常に true または false を返すようにしたいだけです。これを達成するためにクラスファイルを変更する方法を教えてもらえますか?

4

4 に答える 4

5

RULEオーバーライドrtnCLASSFooメソッドはtrueの場合に検証しますtrueENDRULEを返します

http://www.jboss.org/byteman

于 2011-05-30T06:22:21.883 に答える
2

Are you trying to unit test this code and force an answer without caring about the conditions? If that is the case, then you are looking for "Mocking" frameworks. In Java, I can think of Mockito and EasyMock off of the top of my head.

Relatedly, you can use PowerMock (works in tandem with either of the above Mocking frameworks) to dynamically change classes (such as final classes/methods, static methods, and even private pieces of classes). PowerMock actually can change the byte code when necessary. Check under its classloading folders.

I've never considered it, but it might be possible to use any of them within non-test code, but they may require finagling to avoid JUnit dependencies (such as JUnit Runner). Again, I have never thought about it, so I never thought through the implications.

At the very least, you can probably look through PowerMockito to see how they change the byte code.

If you just want to unit test, then it's extremely easy and you probably don't need to worry about the byte code.

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

Test (using Mockito with JUnit 4 (drop the @Test attribute for JUnit 3)):

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());
}
于 2011-05-29T08:28:35.480 に答える
1

提供されたメソッド シグネチャに従って、true または false のみを返すことができます。
バイトコードを操作しようとする代わりに、元の呼び出しを委任し、必要な動作をオーバーライドするラッパー クラスを作成できますか?

于 2011-05-29T06:12:02.200 に答える
1

バイト コードを変更する最も簡単な方法は、クラスを逆コンパイルするか、ソース コードのコピーを取得することです。コードを変更してコンパイルします。新しいバージョンをクラスパスの前に配置するか、jar 内の元のバージョンを置き換えます。このように、方法を変更しました。

実行時に変更できますが、それは 100 倍難しくなります。;)

于 2011-05-29T08:06:07.050 に答える