javaunit-testingjunitjunit4

How to test FacesContext showing a message with JUnit


abort()-Method:

public void abort() {
    LOG.info("some-text");
    warning("some-text");
}

warning()-Method:

 public void warning(String message) {
    FacesContext.getCurrentInstance()
.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "INFO:", message));
}

I want to write a Test-Case for abort which is just verifying that nothing has changed and a second Test-Case which is verifying that warning() is working. I know these two little methods don't need a Unit-Test, but I want to know if it's possible. UI-Test for showing the p:message is working well but I want to check the Caption, Typ and Message by Unittest before because it's running much faster.


Solution

  • working solution with just using JUnit 4.11

    Separate the content from warning() in a own class like this:

    @Named
    @RequestScoped
    public class Resources {
           @Produces
           public FacesContext produceFacesContext() {
                  return FacesContext.getCurrentInstance();
           }
    }
    

    Next you need to define an ArgumentCaptor which can catch the FacesMessage for your JUnit-Test. I´ve created it as a clss member which will be initialized in the @before section and get the null value in @teardown.

    private ArgumentCaptor<FacesMessage> facesMessageCaptor;
    @Before
    public void setUp() {facesMessageCaptor = ArgumentCaptor
                .forClass(FacesMessage.class);
    }
    @After
    public void tearDown() { facesMessageCaptor = null; }
    

    Now you just need to add two @Mocks to your test-class

    @Mock
    Resources resourcesMock; 
    @Mock
    FacesContext facesContextMock;
    

    So you did it! Write the test like this:

    Mockito.doReturn(facesContextMock).when(resourcesMock).produceFacesContext();
    // Execute Method
    cut.warning("SOME_DETAIL_TEXT");
    // Verify interactions with the Resources and Faces and maybe others...
    verify(resourcesMock).produceFacesContext();
    verify(facesContextMock).addMessage(Mockito.anyString() ,
                    facesMessageCaptor.capture());
    verifyNoMoreInteractions(...., resourcesMock, facesContextMock);
    // write assert (i´ve used hamcrast-corematchers - more readable)
    actualMessage = (FacesMessage) facesMessageCaptor.getValue();
    assertThat(FacesMessage.SEVERITY_WARN, is(equalTo(actualMessage.getSeverity())));
    assertThat(MY_TITLE, is(equalTo(actualMessage.getSummary())));
    assertThat("DETAIL_TEXT", is(equalTo(actualMessage.getDetail())));