0

現在、jar で提供される API をテストしています。私たちが触れた、または少なくともソースコードが参照しているjarメソッドとオブジェクトの「カバレッジ」またはリストを取得しようとしています。

私たちが持っている、または利用できるようになるのは、「ここに API のリストがあります」というテキスト形式です。

また、リストされている API をカバーしていることを確認するために、独自のアプリケーションを相互参照する必要があります。

...

簡単な例を次に示します... 以下に、jar から入手できる外部コードの例と、これらの API を使用したコードを示します。

-- EXTERNAL_USE_CLASS -- カバーする必要がある公開 API を使用して外部 JAR をモックします。

package external_api;

public class EXTERNAL_USE_CLASS {
    String myString;
    Integer myInteger;
    Boolean has_ran;
    public EXTERNAL_USE_CLASS() {
        myString = "initial_string";
        myInteger = 4;
        has_ran = false;
    }
    public String getMyString() {
        return myString;
    }
    public void setMyString(String myString) {
        this.myString = myString;
    }
    public Integer getMyInteger() {
        return myInteger;
    }
    public void setMyInteger(Integer myInteger) {
        this.myInteger = myInteger;
    }
    public Boolean getHas_ran() {
        return has_ran;
    }
    public void setHas_ran(Boolean has_ran) {
        this.has_ran = has_ran;
    }
}

私のプロジェクトでは、上記を jar としてインポートし、ビルド パスに追加します。私のコードが行うことは、次のようなものです。

UseExtJar -- 外部 jar オブジェクト/メソッドを使用してテスト アプリケーションをモックします。

import external_api.EXTERNAL_USE_CLASS;

public class UseExtJar {
    static EXTERNAL_USE_CLASS u = new EXTERNAL_USE_CLASS();

    //below is callable via a CLI interface test APP.
    public static void test_basics() {
        Boolean hasRan = u.getHas_ran();
        Integer getInt = u.getMyInteger();
        String getString = u.getMyString();
        System.out.println("u.getHas_ran()"+hasRan);
        System.out.println("u.getMyInteger()"+getInt);
        System.out.println("u.getMyString()"+getString);
    }
}

そして、私が公開したいと思っているのは、外部の Jar から変更されたすべての API です。

(つまり、これらの行になります)

    Boolean hasRan = u.getHas_ran();
    Integer getInt = u.getMyInteger();
    String getString = u.getMyString();

そして、できれば…という趣旨のレポートを印刷できるようにしたいです。

オブジェクト メソッド 'test_basics' は次の API を使用しました:
--external_api.EXTERNAL_USE_CLASS.getHas_ran()
--external_api.EXTERNAL_USE_CLASS.getMyInteger() --external_api.EXTERNAL_USE_CLASS.getMyString()

上記の名前は、テストクラスに移動してEclipseを右クリックし、「修飾名をコピー」と言って取得する必要がありました。

1,000 の API に対してこれを行う必要があるとしたら、これはちょっと面倒なことです....トレースを論理的に出力する方法があると思いました。

適切な Google 検索用語を知らないだけかもしれませんが、これは一般的な簡単な作業です。

ヘルプ/ポインターに感謝します。

4

3 に答える 3

1

クラスの名前がわかっている場合は、リフレクションを使用してこの問題の一部を解決し、それに関する情報を取得できます。クラスのメソッドを印刷して実行することもできます

import java.lang.reflect.*;

public class DumpMethods { 

  public static void main(String args[])
  {
     try {
        Class c = Class.forName("MyClassName");
        Method m[] = c.getDeclaredMethods();
        for (int i = 0; i < m.length; i++)
        System.out.println(m[i].toString());
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }
}

ここに初心者向けのチュートリアルがあります。

負担を軽減するためにライブラリ コードに影響を与えることは、それほど難しいことではありません。

残念ながら、jar の内容を分析することはそれほど単純ではありません。jar のクラスが jar の概念に読み込まれると、そのようなものは消えます。デフォルトのクラスローダーは、一意のクラスを識別し、それがクラスローダーに存在するかどうかを判断するためのキーとしてパッケージ名のみを使用します。そのため、jar の内容は言うまでもなく、パッケージ内のクラスをループすることさえできません。

これを行うには、jar を分析し、クラスパスから丸呑みされたときに情報を記録するカスタム クラスローダーを作成できます。

于 2012-09-01T00:38:15.297 に答える
0

使用する API クラスごとにモック クラスを作成する必要がある場合

System.out.println(MyMockedClass.class.getCanonicalName());

モックしているクラスの修飾名を取得します。

このようなもの

Object doMethod(String name){
    try {
        Method method = u.getClass().getDeclaredMethod(name);
        System.out.println("called: " + name);
        try {
            return (String)method.invoke(this);
        } catch (IllegalArgumentException e) {
            return false;
        } catch (IllegalAccessException e) {
            return false;
        } catch (InvocationTargetException e) {
            return false;
        }
    } catch (NoSuchMethodException e) {
        return false;
    }
}

呼び出す各メソッドを呼び出して出力する方法を提供できます。

引数を指定して呼び出されるメソッドの場合は、より困難になります。

于 2012-09-01T00:55:21.060 に答える
0

Thanks.

I started with reflection as you suggested, and then drifted towards ASM because I'm working with bytecode.


I pulled my reference from 2 links referencing ASM and reflection

Java: Easy way to get method stub out of class files within a JAR file? Reflection?

How can I find all the methods that call a given method in Java?


My solution essentially solves the problem in 2 steps

1. read all the target-methods from the external-jar

ASM を介して、クラス パス (com.my.class.object.*) といくつかの opt-code フィルター (非公開、非抽象など) を満たすパブリックなすべてのクラス/メソッド オブジェクトを読み取り、条件を満たすすべてを追加します。クラス/メソッドを格納するオブジェクトのリストへのフィルタリング。

2. foreach ターゲット メソッドについて、ソース コードに存在するかどうかを確認します。

見つかった各ターゲット クラス/メソッドについて、上記のリンクと同じように、場所を確認し、すべての出現箇所を行/ファイル名などで出力できます。

于 2012-09-01T11:28:03.927 に答える