开发者

How to use mockito to mock facescontext?

How do i mock out facescontext using mockito?

I have made this dummy method:

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

When i run my JUnit test,开发者_如何学Go I get a nullpointer exception when i call getCurrentInstance().

How can I mock out facescontext and write a test, to se if the facesmessage has been added?


Either introduce a FacesContext.setCurrentInstance() (ugly) or don't use a static method.

If you can't change the static method, wrap it in something else like a FacesContextProvider which calls that method. Dependency-inject the provider. Then you can mock that instead.

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


You can try to use MockFacesContext from myfaces. It is very convenient way.


I know it's an old question, but I find my answer useful..

I always use a seperate method that I override with a mock to mock the facesContext.

For example:

BackingBean:

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

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

Test:

private BackingBean backingBean;

@Mock
private FacesContext facesContext;

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


when() requires an argument which has to be 'a method call on a mock'. For example:

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

Also, this error might show up because:

  1. you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified. Mocking methods declared on non-public parent classes is not supported.
  2. inside when() you don't call method on mock but on some other object.


You could use for example PowerMock which is a framework that allows you to extend mock libraries like Mockito with extra capabilities. In this case it allows you to mock the static methods of FacesContext.

Using the Mockito verify() method you could make sure the addMessage() method was called. In addition you could use an ArgumentCaptor in order to retrieve the FacesMessage that was passed to the addMessage() method call on the 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());
}

I've created a blog post which explains the above code sample in more detail.


Since mockito 3.4.0 we can mock static methods without powermock, so we can do this (I'm using JUnit 5.8.1 and 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
    }
}

You can find more details about testing static methods with mockito here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜