2011-01-07 110 views
1

如何使用mockito嘲笑facescontext?如何使用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()。

如何剔除facescontext并编写测试,以确定facesmessage是否已添加?

感谢。

回答

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 ""; 
    } 
} 
+0

该类是一个支持bean,所以构造函数不能带任何参数,或...?是不是可以在我的测试类的setup方法中添加一些东西来设置facescontext的实例? – Chris 2011-01-16 13:58:57

0

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

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

@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其中更详细地解释上面的代码示例。

2

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

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; 
     } 
    }; 
} 
0

when()要求其必须是“上一个模拟一方法调用的参数。 例如:

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

而且,这个错误可能会显示出来,因为:

  1. 你存根任:final/private/equals()/hashCode()方法。 那些方法不能被钉住/验证。 不支持在非公共父类上声明的模仿方法。
  2. 里面when()你不要在模拟上调用方法,而是在其他对象上调用方法。