如何使用mockito来模拟facescontext?

时间:2011-01-07 20:26:06

标签: mocking mockito

如何使用mockito模拟facescontext?

我做了这个虚拟方法:

public String toPage2(){  
    if(isChecked()){  
        return NAV_STRING;  
    } else {  
        FacesContext context = FacesContext.getCurrentInstance();  
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Sæt i kryds checkboxen", null));  
        return "";  
    }  
}  

当我运行JUnit测试时,当我调用getCurrentInstance()时,我得到一个nullpointer异常。

如果添加了facesmessage,我如何模拟facescontext并编写测试?

感谢。

5 个答案:

答案 0 :(得分:2)

引入FacesContext.setCurrentInstance()(丑陋)或不使用静态方法。

如果您无法更改静态方法,请将其包含在调用该方法的FacesContextProvider之类的其他内容中。依赖 - 注入提供者。然后你可以嘲笑它。

public MyClass(FacesContextProvider facesContextProvider) {
    this.facesContextProvider = facesContextProvider;
}

public String toPage2(){  
    if(isChecked()){  
        return NAV_STRING;  
    } else {  

        // Calls FacesContext.GetCurrentInstance() under the hood

        FacesContext context = facesContextProvider.getCurrentInstance();  
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Sæt i kryds checkboxen", null));  
        return "";  
    }  
}  

答案 1 :(得分:2)

您可以尝试使用myfaces中的MockFacesContext。这是非常方便的方式。

答案 2 :(得分:0)

您可以使用 PowerMock ,这是一个允许您使用额外功能扩展 Mockito 等模拟库的框架。在这种情况下,它允许您模拟FacesContext的静态方法。

使用 Mockito verify()方法可以确保调用addMessage()方法。此外,您可以使用ArgumentCaptor来检索FacesMessage上传递给addMessage()方法调用的FacesContext

@Test
public void testToPage2NotChecked() {
    // mock all static methods of FacesContext
    PowerMockito.mockStatic(FacesContext.class);

    FacesContext facesContext = mock(FacesContext.class);
    when(FacesContext.getCurrentInstance()).thenReturn(facesContext);

    NavigationBean navigationBean = new NavigationBean();
    navigationBean.setCheck(false);

    // check the returned value of the toPage2() method
    assertEquals("", navigationBean.toPage2());

    // create an ArgumentCaptor for the FacesMessage that will be added to
    // the FacesContext
    ArgumentCaptor<FacesMessage> facesMessageCaptor = ArgumentCaptor
            .forClass(FacesMessage.class);
    // verify if the call to addMessage() was made and capture the
    // FacesMessage that was passed
    verify(facesContext).addMessage(Mockito.anyString(),
            facesMessageCaptor.capture());

    // get the captured FacesMessage and check the set values
    FacesMessage message = facesMessageCaptor.getValue();
    assertEquals(FacesMessage.SEVERITY_INFO, message.getSeverity());
    assertEquals("Sæt i kryds checkboxen", message.getSummary());
}

我创建了blog post,更详细地解释了上面的代码示例。

答案 3 :(得分:0)

我知道这是一个老问题,但我觉得我的答案很有用..

我总是使用一个单独的方法,我用模拟覆盖来模拟facesContext。

例如:

BackingBean:

public void useFacesContext() {
   findCurrentFacesContext().addMessage("clientId", facesMessage);
}

FacesContext findCurrentFacesContext() {
   return FacesContext.getCurrentInstance();
}

测试:

private BackingBean backingBean;

@Mock
private FacesContext facesContext;

@Before
public void init() {
  backingBean = new BackingBean() {
      @Override
      FacesContext findCurrentFacesContext() {
        return facescontext;
      }
  };
}

答案 4 :(得分:0)

when()需要一个参数,该参数必须是模拟&#39;上的方法调用。 例如:

when(mock.getArticles()).thenReturn(articles);

此外,此错误可能会显示,因为:

  1. 您存储以下任意一种:final / private / equals() / hashCode()方法。 这些方法无法进行存根/验证。 不支持在非公共父类上声明的模拟方法。
  2. when()内,您不会在模拟上调用方法,而是在其他对象上调用方法。