模拟方法作为参数的另一种方法

时间:2015-01-03 15:48:24

标签: java mocking easymock

我在测试调用具体方法(在Operation实例中为IFunction)的次数时遇到了问题。

根据:

  1. http://easymock.org/user-guide.html#mocking-annotations

  2. http://www.ibm.com/developerworks/library/j-easymock/

  3. How to use EasyMock expect

  4. 我写了一些东西:

    class Operation{
       public double[] calculateSth(IFunction function, int [] t){
          for(int i=0 ; i<5 ; i+=1)
              function(t, new int[]{1,2,3});
    
       return new double[]{1,2,3};
       }
    
    }
    
    interface IFunction{
       double f(int[] a, int[]b);
    }
    
    class ConcreteF implements IFunction{
       double f(int[]a, int[]b){
           return 5;
       }
    }
    

    我的测试班:     @考试科目     操作op;

    @Mock
    IFunction function;
    
    @Before
    public void setUp() throws Sth{
        op=new Operation();
        function = EasyMock.createMock(IFunction.class);
    }
    
    @Test
    public void howManyTimes(){
    
    
        EasyMock.expect(function.f(EasyMock.notNull(), EasyMock.notNull())
                       )
        .andReturn((double)EasyMock.anyDouble()).times(3);
    
    
        EasyMock.replay(function);
    
        op.calculateSth(function, new double[]{0,0,0});
    
        //verify
        EasyMock.verify(function);
    
    }
    

    结果:         显示java.lang.NullPointerException

    at org.easymock.internal.Injector.injectMocks(Injector.java:80)
    at org.easymock.EasyMockSupport.injectMocks(EasyMockSupport.java:624)
    at org.easymock.EasyMockRunner.withBefores(EasyMockRunner.java:50)
    

    这是我第一次使用easymock,我不知道如何解决它; /

1 个答案:

答案 0 :(得分:4)

我会回答这个问题,而不会详细说明原始方法是否有用(代码甚至无法编译),更不用说测试方法了。

@TestSubject Operation op;

这条线是嫌犯。我意识到你是在@Before带注释的setUp方法中实例化它,但看起来Easymock试图在它之前注入模拟(用@Mock注释的模拟)做任何事情(并且可以这么理解)并且爆炸,因为那时参考是null

v3.2中引入的注释支持也被视为消除setUp方法需求的一种方法。但你似乎在混淆并错误地使用它。选择其中一个 - 我建议您使用注释。

引用Easymock user guide(此用户指南尽可能好,所以请务必在使用该库之前阅读此内容),

@RunWith(EasyMockRunner.class) 
public class ExampleTest {

  @TestSubject 
  private ClassUnderTest classUnderTest = new ClassUnderTest(); // 2 

  @Mock 
  private Collaborator mock; // 1 

  @Test 
  public void testRemoveNonExistingDocument() { 
    replay(mock); 
    classUnderTest.removeDocument("Does not exist"); 
  } 
}
  

跑步者在步骤1中实例化mock。然后设置为listener   跑步者,到第2步的setUp字段。{{1}}方法可以   因为所有的初始化都是由跑步者完成的。