在单元测试期间最小化对象保留

时间:2011-01-17 07:38:56

标签: java unit-testing memory-leaks

我有一个关于内存管理/内存泄漏的问题,我想澄清一下。

设置:

我正在测试一些servlet代码,它接受HttpServletRequest和HttpResponse对象引用HttpServletRequest#getParameter(String),HttpServletRequest#getHeader(String)和HttpServletRequest#getAttribute(String)。

我正在为servlet代码编写单元测试。为了允许测试,我已经为HttpServletRequest和HttpServletResponse创建了允许测试的存根。示例代码如下:

public final class HttpServletRequestStub implements HttpServletRequest {

  private Map<String, String> parameterMap = new HashMap<String, String>();
  private Map<String, String> headerMap = new HashMap<String, String>();
  private Map<String, String> attributeMap = new HashMap<String, String>();

  public void setParameter(String param, String value) {
    this.parameterMap.put(param, value);
  }
  public void setHeader(String param, String value) {
    this.headerMap.put(param, value);
  }
  @Override
  public void setAttribute(String param, String value) {
    this.attributeMap.put(param, value);
  }
  public void flush() {
     this.parameterMap.clear();
     this.headerMap.clear();
     this.attributeMap.clear();
  }

  @Override
  public String getParameter (String parameter) {
    return this.parameterMap.get(parameter);
  }
  @Override
  public String getHeader(String parameter) {
    return this.headerMap.get(parameter);
  }
  @Override
  public String getAttribute(String attribute) {
    return this.attributeMap.get(attribute);
  }

   .... Other stubbed methods




}

在我的单元测试中:

public class MyTest {
   private MyServlet servlet;

   private HttpServletRequest request;

   private HttpServletResponse response;

   @Before
   public void setUp() throws Exception {
      request = new HttpServletRequestStub();
      response = new HttpServletResponseStub(); // Not in the sample code but implemented.
      servlet = new MyServlet();
   }

   @After
   public void tearDown() throws Exception {
      request = null;
      response = null;
      servlet = null;
   }

  @Test
  public void testFoo() throws Exception {
     request.setParameter("foo", "bar");
     request.setAttribute("attrib", "attrib");
     request.setHeader("header", "header");
     servlet.service(request, response);
  }


}

我的问题是关于内存管理。我是否有必要在测试执行后刷新假标题,请求和属性映射内容,或者一旦请求,响应对象在我的拆卸方法中解除引用(用@After注释),它是否会自动发生?我是否必须在我的拆卸方法中明确调用flush方法来清除内存引用?我想我可能需要使用Weak HashMap而不是HashMap为存根映射设置弱的引用,但我不知道这是否是正确的选择。我仔细阅读了article,现在还不清楚。任何帮助都会有用。

谢谢,

卡尔蒂克

2 个答案:

答案 0 :(得分:1)

取消引用对象应该足够了。 Java垃圾收集器删除所有无法访问的对象,即没有可帮助访问它们的引用。如果您怀疑对象真的消失了,可以使用任何可用的java分析器。

顺便说一下,我可以建议你使用一个可用的Mock对象实现,而不是自己实现像SerbletRequestStub这样的东西吗?例如,请参阅EasyMock。还有一个建议。有JUnit扩展已经实现了所有与Web相关的存根。请参阅Apache Cactus。

答案 1 :(得分:0)

由于单元测试独立性,JUnit为每个测试方法创建了新的MyTest对象。

即,在不同的MyTest实例中调用testFoo()testBar()。您的代码足以解决内存问题,在这种情况下甚至不需要tearDown()。由于以前的MyTest实例可用于GC,因此如果没有其他任何参考,它的成员也可用于GC。

相关问题