Java测试:如何计算对象实例化?

时间:2017-08-09 05:28:14

标签: java testing instantiation

问题是"简单"。与Mockito.verify(myInstance, times(3))类似,在任何测试框架中都有任何可以计算对象实例的内容吗?

我的意思是:

class Obj {
    public void a() {
        new Obj();
    }
}

@Test
@PrepareInstantiationCounter(Obj.class) // <-- this does not exists. I need it
...test... {
    new Obj().a();
    InstantiationCounters.countOf(Obj.class) // This also does not exists, I would expect 2
}

我希望我的例子可以让你知道我想要获得什么。

3 个答案:

答案 0 :(得分:0)

遗憾的是,我不知道任何提供此功能的框架。 但是,您可以做的是修改或覆盖给定类的构造函数和finalize方法,并将计数器存储在静态变量中。

public class MyClass {
    public static int instances = 0;

    public MyClass(/*Args*/){
        ...
        MyClass.instances++;
    }

    @Override
    protected void finalize() {
        super.finalize();
        --MyClass.instances;
    }

}

希望这有帮助。

答案 1 :(得分:0)

你可以在类中定义一个静态字段,并在类构造函数中递增它,如下所示:

class MyClass
{
    public static void main (String[] args)
    {
        obj test=new obj();
        System.out.print(obj.counter); //the result will be 1
    }
}

class obj{
    static int counter=0;
    obj(){
        counter++;
    }
}

或者如果您希望计数器是私有的,您可以使用公共方法返回它:

class MyClass
{
    public static void main (String[] args)
    {
        obj test=new obj();
        System.out.print(obj.numberOfInstances()); //the result will be 1
    }
}

class obj{
    private static int counter=0;
    obj(){
        counter++;
    }
    public static int numberOfInstances(){
        return counter;
    }
}

答案 2 :(得分:0)

您可以使用JDI界面来计算对象。它配备了JDK。要使用它,请在类路径中包含tools.jar文件。我使用JUnit 4编写了一个代码示例。

public class MarsRover {
    public String toString() {
        return "I'm a cool robot";
    }
}

private static VirtualMachine vm;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
    List<AttachingConnector> acl = vmm.attachingConnectors();

    for(AttachingConnector ac: acl) {
        if(ac.transport().name().equals("dt_socket")) {
            Map<String, Connector.Argument> arg = ac.defaultArguments();
            arg.get("port").setValue("3001");
            arg.get("timeout").setValue("30");

            vm = ac.attach(arg);
        }
    }
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
    vm.dispose();
}

public static long[] getObjectCount(Class<?> c) {
    return vm.instanceCounts(vm.classesByName(c.getName()));
}

@Test
public void test() {
    final long[] objectCount;
    final List<MarsRover> mrArray = Arrays.asList(new MarsRover(), new MarsRover(), new MarsRover());
    objectCount = getObjectCount(MarsRover.class);
    assertThat(objectCount.length, is(1));
    assertThat(objectCount[0], is(3L));
}

要运行此代码,您需要在Java调用中添加以下选项:

-Xrunjdwp:transport=dt_socket,address=3001,server=y,suspend=n

这个BeyoundJava article给了我这个解决方案的基本想法。