我得到以下NullPointerException

Caused by: java.lang.NullPointerException at FacadeBean.createRegistration(FacadeBean.java:389)


FacadeBean.java下:

private SessionContext context

public CreateRegistrationResponse createRegistration() {
  try {
    // snip
  } catch (DataAccessException de){
    context.setRollbackOnly(); //---------line 389
    throw new ServiceException("Error");
  }
}


测试班

@Test(expected = ServiceException.class)
public void testCreateRegistrationError() throws ServiceException {
    doThrow(DataAccessException.class).when(mockRegistrationPeristenceImpl).create(any(Registration.class));
    facadeBeanTest.createRegistration(RegistrationFacadeMock.getCreateRegistrationRequest());
}


有人可以告诉我如何模拟下面的行,以便我可以忽略此context.setRollbackOnly();

public class FacadeBean {
  public FacadeBean() {}
  @Resource
  private SessionContext context
}

最佳答案

最简单的方法是将类更改为使用method injection而不是字段注入。

换句话说,在您的实际课堂中,更改此内容:

@Resource
private SessionContext context;


到这个:

private SessionContext context;

@Resource
public void setSessionContext(SessionContext sessionContext) {
 this.sessionContext = sessionContext;
}


然后,一旦完成,就可以使用单元测试注入一个模拟:

@Before
public void setUp() {
  // You probably have other code here already
  facadeBean.setSessionContext(mock(SessionContext.class));
}


但是,如果这样做,可能会对JAXB产生问题。如果发生这种情况,请阅读以下问题:SessionContext Injection using @Resource annotation



如果您无法更改代码,则可能可以通过反射来访问该字段,如下所示:

@Before
public void setUp() {
  Field sessionContextField = FacadeBean.class.getDeclaredField("context");
  sessionContextField.setAccessible(true);
  sessionContextField.set(beanObject, mock(SessionContext.class));
}

10-07 19:03
查看更多