2013-03-11 105 views
0

我一直在尝试使用mockito和junit运行以下测试,并且我一直在获取“java.lang.NullPointerException:名称不能为空” 任何人都可以告诉我为什么会这样呢?Mockito&Junit空指针异常:名称不能为空

在调试时,我发现,当测试执行isStopValid(String)方法下面的语句则抛出该异常:

FacilityValidationUtil facUtil =新FacilityValidationUtil();

@RunWith(MockitoJUnitRunner.class) 
public class MyFormTest{ 
    @InjectMocks MyForm form = new MyForm(); 
    @Mock FacilityValidationUtil facUtil; 
    @Test 
    public void testIsStopValid() throws FinderException{ 
     when(facUtil.isFacilityValid("")).thenReturn(false); 
     form.setOrigin(""); 
     assertEquals(false, form.isStopValid(form.getOrigin()));   
    } 
} 

与方法类待测试:

public class MyForm{ 
    FacilityValidationUtil facUtil = new FacilityValidationUtil(); 
    public boolean isStopValid(String stop){ 

     try { 
      return facUtil.isFacilityValid(stop); 
     } catch (FinderException e) { 
      log.error("Error finding the stop. "+e.getCause()); 
      return false; 
     } 
    } 
} 

public class FacilityValidationUtil{ 
    private FacilityDAO facilityDao = new HibernateFacilityDAO(); 
    public boolean isFacilityValid(String facility) throws FinderException{ 
     boolean test; 
     FacilityImpl facilityImpl = facilityDao.findFacilityByNassCode(facility); 
     test = (facilityImpl==null)?false : true; 
     return test; 
    } 
} 

public class HibernateFacilityDAO extends HibernateAbstractDeltaDAO implements FacilityDAO { 
    public HibernateFacilityDAO() { 
     super(false); 
    } 
} 
+0

'testIsStopValid()'中的哪一行导致异常? – Magnilex 2013-03-11 17:41:13

+0

@MagnusTengdahl assertEquals(false,form.isStopValid(form.getOrigin()));谢谢。 – Susie 2013-03-11 17:42:26

回答

2

短答案:试图嘲笑一个变量(facUtil),该是您的isStopValid会见的本地hod,所以在你的测试中这个对象的模拟版本永远不会被调用,因为你每次都在“新建”它。

Long答案:它看起来像你试图嘲弄你的FacilityValidationUtil类的调用,如果是这种情况,那么你需要或者让这个类成为一个字段,以便Mockito可以通过反射注入对象(if这个对象是线程安全的,看起来是这样的),或者探索一个像PowerMockito这样的模拟框架,它可以让你模拟一个构造函数(新的PowerMockito时为Google)。

PowerMockito.whenNew(FacilityValidationUtil.class).withNoArguments().thenReturn(facUtil); 

Mockito默认不支持构造函数参数的任何模仿。

编辑 如果您仍然有麻烦,那么我会建议从一个较小的例子开始。我已经为你制作了一个适用于你的代码,并且使用了你正在测试的代码(尽管它使用内部类,Mockito有一些古怪的规则,但我只是在压缩这个例子)。

@RunWith(MockitoJUnitRunner.class) 
public class MyFormTest { 

@InjectMocks 
private MyForm form = new MyForm(); 
@Mock 
private FacilityValidationUtil facUtil; 

@Test 
public void testIsStopValid_false() { 
    when(facUtil.isFacilityValid("")).thenReturn(false); 
    assertEquals(false, form.isStopValid("")); 
} 

@Test 
public void testIsStopValid_true() { 
    when(facUtil.isFacilityValid("")).thenReturn(true); 
    assertEquals(true, form.isStopValid("")); 
} 

public class MyForm { 
    private FacilityValidationUtil facUtil = new FacilityValidationUtil(); 

    public boolean isStopValid(String stop) { 
     try { 
      return facUtil.isFacilityValid(stop); 
     } catch (FinderException e) { 
      return false; 
     } 
    } 
} 

public class FacilityValidationUtil { 
    public boolean isFacilityValid(String facility) throws FinderException { 
     throw new RuntimeException(facility); 
    } 
} 

public class FinderException extends RuntimeException { 
    public FinderException(String message) { 
     super(message); 
    } 
} 

}

什么是真正重要的是你的模仿是没有得到正确的注射。直到你得到解决,你将继续得到相同的错误。在调用facUtil.isFaciltyValid的地方设置MyForm中的一个断点并查看该对象。它应该是一个mockito对象,而不是你的班级。

祝你好运。

+0

我做了facUtil一个类对象。我上面编辑了我的代码。我仍然得到同样的错误。奇怪的是,现在我所有的其他测试都以相同的错误失败。 – Susie 2013-03-11 21:01:17

+0

我刚刚为你添加了更多信息。你应该可以将它复制到一个类文件中,然后尝试一下,而不会有太多的麻烦。让我知道你是否需要更多的帮助。 – benkiefer 2013-03-11 22:20:37