簡體   English   中英

如何在內部類中對方法進行單元測試?

[英]How can i unittest a method in a inner-class?

我已經用一個內部類使這個單例。 我想對該方法進行單元測試:運行。 現在我發現我應該反思,但是我不知道該怎么做。 是否可以對該方法進行單元測試:運行? 如何?

package monitor;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.util.Hashtable;
import java.util.List;
import java.util.Map; 
import java.util.Timer;
import java.util.TimerTask;
import com.gesmallworld.magik.commons.runtime.annotations.MagikProc;
import com.gesmallworld.magik.commons.runtime.objects.Char16Vector;

public class UsedMemory{
    private static UsedMemory theInstance;

    private static synchronized UsedMemory getInstance() {
        if( theInstance == null) {
            theInstance = new UsedMemory();
        }
        return theInstance;
    }

    private Map<String, MemorySampler> MEMORY_SAMPLERS = new Hashtable<String, MemorySampler>();

    private MemorySampler getMemorySampler(String memoryPool) {
        MemorySampler sampler = MEMORY_SAMPLERS.get(memoryPool);
        if (sampler == null) {
            sampler = new MemorySampler(memoryPool);
            MEMORY_SAMPLERS.put(memoryPool, sampler);
        }
       return sampler;
    }

    @MagikProc(name="rw_diag_setupusedmemory")
    public static void setupUsedMemory(Object proc, Char16Vector memoryPool, int timer){
        new Timer().schedule(getInstance().getMemorySampler(memoryPool.toString()), 0, timer);
    }

    @MagikProc(name="rw_diag_usedmemory")
    public static Char16Vector getUsedMemory(Object proc, Char16Vector memoryPool){
        return getInstance().getMemorySampler(memoryPool.toString()).getUsedMemoryString();
    }

    private class MemorySampler extends TimerTask {
        private MemoryPoolMXBean mxbean;
        private int byteToMb = 1048576;
        private long min = 0;
        private long avg = 0;
        private long count = 0;
        private long max = 0;

        public MemorySampler(String memoryPool) {
            mxbean = getMemoryPoolMXBean(memoryPool);
        }

        private Char16Vector getUsedMemoryString(){
            long minTemp = min;
            long avgTemp = avg;
            long maxTemp = max;
            min = 0;
            avg = 0;
            max = 0;
            count = 0;
            return new Char16Vector(minTemp/byteToMb+"__"+avgTemp/byteToMb+"__"+maxTemp/byteToMb);
        }

        @Override
        public void run() {
            long used = mxbean.getUsage().getUsed();
            if(min==0 || used < min){
                min = used;
            }
            if(max==0 || used > max){
                max = used;
            }
            if(count==0){
                avg = used;
            } else {
                avg=((avg*count)+used)/(count+1);
            }
            count +=1;
        }

        private MemoryPoolMXBean getMemoryPoolMXBean(String pool){
            List<MemoryPoolMXBean> mxbean = ManagementFactory.getMemoryPoolMXBeans();
            for(MemoryPoolMXBean mPool: mxbean){
                if(mPool.getName().equals(pool)){
                    return mPool;
                }
            }
            return null;
        }
    }
}

在分析了您的主類和私有類之后,不需要將該私有類作為內部類,因為該類與包含它的類沒有任何關系:內部類不引用任何變量或方法封閉類。

最好的解決方案是更改設計,將內部類提取為非內部公共類,然后像往常一樣對其進行測試。

如果您不想更改設計,或者由於某種原因而不能更改設計(例如,代碼可以按照需要保持原樣的方式發展或增長),則必須使用反射等更高級的機制。 在這種情況下,您可以檢查以下問題:

如何測試具有私有方法,字段或內部類的類?

我看起來MemorySampler不依賴於UsedMemory的實例,因此可以將其設置為靜態。 然后,如果將訪問級別更改為默認級別而不是私有級別,則可以從同一程序包中的單元測試中訪問它。

static class MemorySampler extends TimerTask {
    ...
}

在單元測試課中:

@Test
public void test() {
    UsedMemory.MemorySampler sampler = new UsedMemory.MemorySampler("memoryPool");
    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM