Reputation: 15
I've made this singleton with a inner class. I would like to make a unittest for the method: run. Now I found that i should do that with reflection, but I have no idea how to do that. Is it possible to make a unittest for the method: run? and how?
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;
}
}
}
Upvotes: 1
Views: 1373
Reputation: 2983
I looks like MemorySampler
doesn't depend on an instance of UsedMemory
, so you can make it static. Then if you change the access level to default instead of private, you'll be able to access it from a unit test in the same package.
static class MemorySampler extends TimerTask {
...
}
In your unit test class:
@Test
public void test() {
UsedMemory.MemorySampler sampler = new UsedMemory.MemorySampler("memoryPool");
...
}
Upvotes: 0
Reputation: 1449
After analyzing your main class and the private class, there is no need of that private class being an inner class, because that class isn't related in any way with the class containing it: the inner class doesn't reference any variables or methods of the enclosing class.
The best solution would be to change your design, extracting the inner class into a non-inner public class, and then to test it as usual.
If you don't want to change the design or you can't change it for some reason (i.e. the code can evolve or grow in some way that you need it to stay as it is) you must use more advanced mechanisms like reflection. In that case you can check this question:
How do I test a class that has private methods, fields or inner classes?
Upvotes: 2