2

我的目标是列出我项目的公共 API 类的所有传递依赖项,并使用它来集中测试工作,以防对这些依赖项进行任何代码更改。

例如:

class MyApi {
    MyDao md;
    public void methodA() {
        //do something with md;
    }
}

interface MyDao { }

class MyDaoImpl implements MyDao { }

因此,如果我知道 MyDaoImpl 已被修改(比如从提交历史记录中)并且我知道 MyApi.methodA 使用 MyDaoImpl,那么我的测试应该专注于检查它。我需要 MyApi.methodA() 的依赖项列表,包括 MyDao 和 MyDaoImpl。

到目前为止,我已经尝试了两种工具 - https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.htmlhttp://depfind.sourceforge.net/ - 他们很有希望,但似乎不能完全解决问题。对于这两种工具来说,如果一个类依赖于一个接口,似乎没有内置方法将该接口的实现包含为传递依赖项。

有没有办法从任何工具中提取这些信息而无需大量定制?

4

1 回答 1

1

您可以根据需要使用JArchitect。右键单击 UI 中任意位置的方法,然后选择菜单:选择方法... > ...正在使用我(直接或间接)会导致代码查询,例如:

from m in Methods 
let depth0 = m.DepthOfIsUsing("myNamespace.MyClass.MyMethod()")
where depth0  >= 0 orderby depth0
select new { m, depth0 }

问题是这样的查询提供了间接使用,但不查找通过接口(或在基类中声明的重写方法)发生的调用。

希望您可以通过以下查询获得您所要求的内容:

// Retrieve the target method by name
let methodTarget = Methods.WithFullName(""myNamespace.MyClass.MyMethod()"").Single()

// Build a ICodeMetric<IMethod,ushort> representing the depth of indirect
// call of the target method.
let indirectCallDepth = 
   methodTarget.ToEnumerable()
   .FillIterative(
       methods => methods.SelectMany(
          m => m.MethodsCallingMe.Union(m.OverriddensBase)))

from m in indirectCallDepth.DefinitionDomain
select new { m, callDepth = indirectCallDepth[m]  }

此查询的两个基石是:

  • 调用 FillIterative() 以递归方式选择间接调用。
  • 顾名思义,对属性 IMethod.OverriddensBase 的调用。对于方法M这将返回在基类或接口中声明的所有方法的可枚举,由M覆盖。
于 2017-08-12T15:46:08.463 回答