2

如何使用 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?

4

6 回答 6

2

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

于 2015-04-10T13:50:27.363 回答
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 "";  
    }  
}  
于 2011-01-13T21:15:41.727 回答
0

例如,您可以使用PowerMock,它是一个允许您扩展Mockito等具有额外功能的模拟库的框架。在这种情况下,它允许您模拟FacesContext.

使用Mockito verify()方法,您可以确保addMessage()调用了该方法。此外,您可以使用 anArgumentCaptor来检索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());
}

我创建了一篇博文,更详细地解释了上述代码示例。

于 2014-11-09T19:30:04.163 回答
0

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

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

例如:

支持豆:

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;
      }
  };
}
于 2015-05-26T09:57:34.870 回答
0

when()需要一个参数,该参数必须是“模拟方法调用”。例如:

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

此外,可能会出现此错误,因为:

  1. 你存根其中一个:final///方法。这些方法不能被存根/验证。不支持在非公共父类上声明的模拟方法。privateequals()hashCode()
  2. 在内部when(),您不会在模拟上调用方法,而是在其他对象上调用方法。
于 2016-05-31T06:38:07.573 回答
0

由于 mockito 3.4.0 我们可以在没有 powermock 的情况下模拟静态方法,所以我们可以这样做(我使用的是JUnit 5.8.1和 mockito core / inline 4.0.0):

@Test
void myTest() {
    try (MockedStatic<Logger> logger = mockStatic(Logger.class, RETURNS_DEEP_STUBS); //Need it for UIViewRoot initialization
        MockedStatic<FacesContext> context = mockStatic(FacesContext.class,
            Mockito.RETURNS_DEEP_STUBS)) {
        //test logic
    }
}

您可以在此处找到有关使用 mockito 测试静态方法的更多详细信息。

于 2021-10-31T05:22:05.753 回答