如何单元测试副作用逻辑

时间:2016-01-03 18:00:55

标签: java unit-testing aem side-effects

我有以下代码

public class Component extend Framework {
  private Integer someInt;  
  private String someString;    
  public Integer getSomeInt() {
    return someInt;
  }    
  public String getSomeString() {
    return someString;
  }
  public void activate() {
     Integer tempInt = (Integer)getProperties("key"); // From Framework
     if (tempInt == null) {
         tempInt = (Integer)getRequest().getProperties("key"); // From Framework        
     }

     if(tempInt == null)
        tempInt = (Integer)getBind().getProperties("key"); // From Frameowrk 
     someString = makeServiceCall("http://.....?key=tempInt");
  }
}

基本上,由框架调用activate()方法,以便访问框架的内部状态来构造Component对象。 activate()有点像Component对象的setter。 如果我要对上面的代码进行单元测试,那么在不运行框架的情况下,最好的方法是什么?

一种方法是模拟Component类并存根super.getProperties ...调用,但是如果我们模拟有问题的类,那么测试的重点是什么?

3 个答案:

答案 0 :(得分:1)

使用Mockito。 窥探Component类并模拟方法getRequest()和getBind()。 最后,直接从单元测试中调用activate()方法。

答案 1 :(得分:1)

我将展示如何测试一个边缘案例

void testServiceCallWithNoKeyPropertyFound() {
  Component componentUnderTest = new Component() {
    Integer getProperties(String key) {
       return null; // property should not be found
    }

    Request getRequest() {
      return new Request(...); //this request should not contain a property named "key", 
    }

    Bind getBind() {
      return new Bind(...); //this bind should not contain a property named "key"
    }

    String makeServiceCall(String url) {
      if (url.endsWith("null")) {
        return success;
      }
      throw new AssertionError("expected url ending with null, but was " + url);
    }

  };
  componentUnderTest.activate();
  assertThat(componentUnderTest.getSomeString(), equalTo("success"));
}

使用Mockito(spys)可以使这个例子更加简洁。但这会隐藏如何设计测试的原则。

还有一些边缘案例:

void testServiceCallWithPropertyFoundInComponent() ...
void testServiceCallWithPropertyFoundInRequest() ...
void testServiceCallWithPropertyFoundInBind() ...

答案 2 :(得分:-1)

我认为这可能是一种糟糕设计的气味。也许你应该考虑构成而不是继承?它会更友好,更客观。为什么Component继承自Framework类?

public class Component {
  private int someInt;  
  private String someString;  
  private Framework framework;  

  public Component(Framework framework) {
    this.framework = framework
  }

  public int getSomeInt() {
    return someInt;
  }    
  public String getSomeString() {
    return someString;
  }
  public void activate() {
     int tempInt = framework.getProperties("key"); // From Framework
     if (tempInt == null) {
         tempInt = framework.getRequest().getProperties("key"); // From Framework        
     }

     if(tempInt == null)
        tempInt = framework.getBind().getProperties("key"); // From Frameowrk 
        someString = makeServiceCall("http://.....?key=tempInt");
  }
}