Mocking FacesContext

前端 未结 7 1110
执念已碎
执念已碎 2021-02-18 19:20

I am trying to add some unit tests to a JSF application. This application didnt rely heavily on any best practices, so many service methods use the FacesContext to

7条回答
  •  暖寄归人
    2021-02-18 19:46

    This url provides a really good article on it: http://illegalargumentexception.blogspot.com/2011/12/jsf-mocking-facescontext-for-unit-tests.html

    You have your managed bean:

     package foo;
    
    import java.util.Map;
    
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.RequestScoped;
    import javax.faces.context.FacesContext;
    
    @ManagedBean
    @RequestScoped
    public class AlphaBean {
      public String incrementFoo() {
        Map session = FacesContext.getCurrentInstance()
            .getExternalContext()
            .getSessionMap();
        Integer foo = (Integer) session.get("foo");
        foo = (foo == null) ? 1 : foo + 1;
        session.put("foo", foo);
        return null;
      }
    }
    

    You stub out the FacesContext:

    package foo.test;
    
    import javax.faces.context.FacesContext;
    
    import org.mockito.Mockito;
    import org.mockito.invocation.InvocationOnMock;
    import org.mockito.stubbing.Answer;
    
    public abstract class ContextMocker extends FacesContext {
      private ContextMocker() {
      }
    
      private static final Release RELEASE = new Release();
    
      private static class Release implements Answer {
        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
          setCurrentInstance(null);
          return null;
        }
      }
    
      public static FacesContext mockFacesContext() {
        FacesContext context = Mockito.mock(FacesContext.class);
        setCurrentInstance(context);
        Mockito.doAnswer(RELEASE)
            .when(context)
            .release();
        return context;
      }
    }
    

    Then write your unit test:

    @Test
      public void testIncrementFoo() {
        FacesContext context = ContextMocker.mockFacesContext();
        try {
          Map session = new HashMap();
          ExternalContext ext = mock(ExternalContext.class);
          when(ext.getSessionMap()).thenReturn(session);
          when(context.getExternalContext()).thenReturn(ext);
    
          AlphaBean bean = new AlphaBean();
          bean.incrementFoo();
          assertEquals(1, session.get("foo"));
          bean.incrementFoo();
          assertEquals(2, session.get("foo"));
        } finally {
          context.release();
        }
      }
    

提交回复
热议问题