【问题标题】:Minimizing object retention during unit tests在单元测试期间最大限度地减少对象保留
【发布时间】:2011-01-17 07:38:56
【问题描述】:

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

设置:

我正在测试一些使用 HttpServletRequest 和 HttpResponse 对象引用 HttpServletRequest#getParameter(String)、HttpServletRequest#getHeader(String) 和 HttpServletRequest#getAttribute(String) 的 servlet 代码。

我正在为 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 方法来清除内存引用?我想我可能需要使用 Wea​​k HashMap 而不是 HashMap 为存根映射设置弱引用,但我不知道这是否是正确的选择。我通读了这个article,但仍然不清楚。任何帮助都会很有用。

谢谢,

卡提克

【问题讨论】:

    标签: java unit-testing memory-leaks


    【解决方案1】:

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

    顺便说一句,我可以建议您使用 Mock 对象的可用实现之一,而不是自己实现 SerbletRequestStub 之类的东西吗?例如,参见 EasyMock。还有一个建议。有些 JUnit 扩展已经实现了所有与 Web 相关的存根。请参阅阿帕奇仙人掌。

    【讨论】:

      【解决方案2】:

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

      也就是说,testFoo()testBar() 在不同的 MyTest 实例中被调用。您的代码足以记忆问题,在这种情况下甚至不需要tearDown()。由于之前的 MyTest 实例可用于 GC,因此其成员也可用于 GC,如果没有其他引用它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        相关资源
        最近更新 更多