myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kito Mann <kito.m...@virtua.com>
Subject Re: [core][mftest][discuss] Create new module for JUnit Mock Testing using MyFaces Core, MyFaces Test and CDI (OWB)
Date Fri, 31 Jan 2014 19:50:27 GMT
Hmm.. okay. But doesn't this sort of make MyFacesTest obsolete? Or am I
missing something...

___

Kito D. Mann | @kito99 | Author, JSF in Action
Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and consulting
http://www.JSFCentral.com | @jsfcentral
+1 203-998-0403

* Listen to the Enterprise Java Newscast: *http://w
<http://blogs.jsfcentral.com/JSFNewscast/>ww.enterprisejavanews.com
<http://ww.enterprisejavanews.com>*
* JSFCentral Interviews Podcast:
http://www.jsfcentral.com/resources/jsfcentralpodcasts/
* Sign up for the JSFCentral Newsletter: http://oi.vresp.com/?fid=ac048d0e17


On Sat, Jan 25, 2014 at 10:17 PM, Leonardo Uribe <lu4242@gmail.com> wrote:

> Hello Kito
>
> It is not possible to include it into MyFaces-Test by several reasons:
>
> - MyFaces Core has a dependency over MyFaces Test. This code is in
> between both projects, so if we include it into MyFaces Test it means
> we will have a circular dependency between both projects.
> - The code includes some small but important changes for MyFaces Core.
> It is easier to maintain these details if the resulting module is
> released along with MyFaces Core, and it will be easier for users to
> know which version of the module is compatible with, because the
> released module will have the same release version numbers as MyFaces
> Core.
> - This code is needed to test Myfaces Core code, because we have
> already a bunch of test cases using this stuff.
>
> The code has been used for some time, and the idea is improve it and
> give the opportunity to users to include it into their projects, and
> also use it in other MyFaces projects in the future.
>
> regards,
>
> Leonardo
>
>
> 2014-01-25 Kito Mann <kito.mann@virtua.com>:
> > Hello Leonardo,
> >
> > This sounds very cool. Why not add it to MyFaces-Test instead?
> >
> >
> > On Saturday, January 25, 2014, Leonardo Uribe <lu4242@gmail.com> wrote:
> >>
> >> Hi
> >>
> >> With JSF 2.0/2.1 and with the introduction of JSF 2.2, it has become
> more
> >> and
> >> more frequent to find cases where you have a JSF-CDI application, and
> you
> >> want
> >> to create JUnit tests. Usually, the interest in these cases is test some
> >> complex server side logic, but the problem is you usually need some
> >> control of
> >> the JSF lifecycle, or there is an interaction between pages and beans
> and
> >> with a mocked environment like the one provided in MyFaces Test you can
> >> only
> >> simulate partially the beans. In these cases, it is not necessary to
> fully
> >> simulate the client, because what you really want to check is what's
> going
> >> on
> >> in the server side.
> >>
> >> Solutions like the one provided by JSFUnit or Arquillian does not fit
> >> properly
> >> in these cases, because the server does not run on the same side as the
> >> client,
> >> so there are 2 running classloaders (the one where junit is and the
> other
> >> that belongs to the web server) which makes debugging difficult.
> >>
> >> Additionally, some time ago, these issues were opened in MYFACESTEST
> issue
> >> tracker:
> >>
> >> - MYFACESTEST-42 Implement support for creating managed beans from
> >>                  faces-config.xml or other JSF config files.
> >> - MYFACESTEST-59 Move MockViewDeclarationLanguageFactory from MyFaces
> Core
> >> to
> >>                  MyFaces-test
> >> - MYFACESTEST-62 Move FaceletTestCase from internal MyFaces to the
> MyFaces
> >>                  Test project
> >>
> >> These issues suggest it would be great to have some mock test
> environment
> >> that
> >> can do things like build a view from a .xhml or read faces-config.xml or
> >> .taglib.xml files. In few words, run MyFaces Core in a JUnit test.
> >>
> >> Looking for a way to fix this problem, some time ago it was created this
> >> issue:
> >>
> >> https://issues.apache.org/jira/browse/MYFACES-3376 Create abstract test
> >> classes
> >>                                         that runs MyFaces Core as in a
> >> container
> >>
> >> Inside MyFaces Core Impl module, in src/test/java directory there is a
> >> package
> >> called org.apache.myfaces.mc.test.core with these junit base test
> classes:
> >>
> >> - AbstractMyFacesTestCase
> >> - AbstractMyFacesRequestTestCase
> >> - AbstractMyFacesFaceletsTestCase
> >> - AbstractMyFacesCDIRequestTestCase
> >>
> >> These classes creates a mock servlet test environment that is able to
> run
> >> MyFaces Core using JUnit. For example:
> >>
> >> // 1. In pom.xml it is necessary to make available src/main/webapp
> >> resources
> >> // as test resources:
> >>
> >> <build>
> >>     <testResources>
> >>         <testResource>
> >>             <directory>${project.basedir}/src/test/resources</directory>
> >>         </testResource>
> >>         <testResource>
> >>             <directory>${project.basedir}/src/main/webapp</directory>
> >>             <targetPath>webapp</targetPath>
> >>         </testResource>
> >>     </testResources>
> >>     <!-- .... -->
> >>
> >> // 2. Add beans.xml in src/main/java/META-INF and src/test/java/META-INF
> >> // 3. Now create the test class
> >>
> >> public class SimpleTestCase extends AbstractMyFacesCDIRequestTestCase
> >> {
> >>     @Inject
> >>     @Named("helloWorld")
> >>     private HelloWorldController helloWorldBean;
> >>
> >>     @Test
> >>     public void testHelloWorld() throws Exception
> >>     {
> >>         startViewRequest("/helloWorld.xhtml");
> >>         processLifecycleExecute();
> >>         Assert.assertEquals("page2.xhtml", helloWorldBean.send());
> >>         renderResponse();
> >>
> >>         client.inputText("mainForm:name", "John Smith");
> >>         // The button end current request and start a new request
> >>         // with a simulated submit
> >>         client.submit("mainForm:submit");
> >>
> >>         processLifecycleExecute();
> >>         Assert.assertEquals("John Smith", helloWorldBean.getName());
> >>         Assert.assertEquals("/page2.xhtml",
> >>                          facesContext.getViewRoot().getViewId());
> >>         endRequest();
> >>     }
> >>
> >>     @Override
> >>     protected ExpressionFactory createExpressionFactory()
> >>     {
> >>         // By default it uses a mock ELFactory.
> >>         return new com.sun.el.ExpressionFactoryImpl();
> >>     }
> >>
> >>     @Override
> >>     protected String getWebappContextFilePath()
> >>     {
> >>         // By default it is the package name of the test.
> >>         return "webapp";
> >>     }
> >>
> >> }
> >>
> >> The example simulates a helloworld submit. getWebappContextFilePath()
> >> defines
> >> the link between the webapp context as test resource, to allow the test
> to
> >> load the resources from that location. All faces-config.xml and
> >> .taglib.xml
> >> from the classpath are automatically loaded. JSF annotation scanning is
> >> disabled by default but you can enable it overriding isScanAnnotations()
> >> method and setting up "org.apache.myfaces.annotation.SCAN_PACKAGES"
> param
> >> to reduce the time spent in classpath scanning.
> >>
> >> This code has allowed us to make very complex tests inside MyFaces Core
> >> very
> >> easily, like Faces Flows, Resource Library Contracts, Reset Values or
> View
> >> Pooling. The resulting simulated environment is almost identical in
> >> comparison
> >> with the one created inside a web server, and the differences can be
> fixed
> >> quite easily, overriding the appropiate methods. The integration with
> >> CDI is just register the servlet listener and that's it.
> >>
> >> If users are using some JSF third-party component library, it is quite
> >> easy
> >> to create a custom mock client and use Firebug or something else to
> check
> >> the http requests and provide some methods to fill the simulated client
> >> side logic.
> >>
> >> Create test cases is pretty straightforward, because everything is
> running
> >> in the junit test case, so you don't need to write any callback, just
> >> write
> >> the instructions and do the necessary validations in the right spots.
> This
> >> is
> >> how a redirect is simulated:
> >>
> >>     @Test
> >>     public void testRedirect1() throws Exception
> >>     {
> >>         startViewRequest("/redirect1.xhtml");
> >>         processLifecycleExecute();
> >>         renderResponse();
> >>         client.submit("mainForm:submit");
> >>         processLifecycleExecuteAndRender();
> >>         // redirect sends 302 response, so the client must take it and
> >>         // start the redirected request
> >>         client.processRedirect();
> >>         // this is the lifecycle of the redirected request.
> >>         processLifecycleExecuteAndRender();
> >>         String redirectedContent = getRenderedContent();
> >>         Assert.assertTrue(redirectedContent.contains("Redirected
> Page"));
> >>     }
> >>
> >> The code tries to reuse as much configuration info as possible. For
> >> example
> >> a test case like FlowMyFacesRequestTestCase in my machine in Netbeans
> >> takes 2.5 seconds to be executed and then 0.17 seconds per each
> additional
> >> test, and the IDE takes another 3 or 4 seconds to execute
> >> "compile on save" and start junit. CDI takes about 1.1 seconds per
> method.
> >> Note this is a lot less than deploy a server like jetty or tomee, which
> in
> >> the same conditions could take (with a helloworld app) about 10 seconds
> or
> >> more to start, run the test and stop.
> >>
> >> The proposal I have for the consideration of MyFaces community is
> create a
> >> new module for MyFaces Core 2.2 branch called impl-test. The module
> takes
> >> the code from org.apache.myfaces.mc.test.core in impl module and
> repackage
> >> it into a new jar file so users can reference it into its own projects.
> >> In that way we can use the code in MyFaces Core like we are doing right
> >> now and we can maintain it at the same time.
> >>
> >> This is the issue in jira to keep track of this feature:
> >>
> >> https://issues.apache.org/jira/browse/MYFACES-3849
> >>
> >> I have already committed the necessary code so you can just take it from
> >> trunk and try it. If no objections, I'll include the module into the
> next
> >> release of MyFaces Core. This is also a good moment to provide ideas
> about
> >> how to improve this feature, so suggestions are welcomed.
> >>
> >> regards,
> >>
> >> Leonardo Uribe
> >
> >
> >
> > --
> > ___
> >
> > Kito D. Mann | @kito99 | Author, JSF in Action
> > Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and
> consulting
> > http://www.JSFCentral.com | @jsfcentral
> > +1 203-998-0403
> >
> > * Listen to the Enterprise Java Newscast:
> http://www.enterprisejavanews.com
> > * JSFCentral Interviews Podcast:
> > http://www.jsfcentral.com/resources/jsfcentralpodcasts/
> > * Sign up for the JSFCentral Newsletter:
> http://oi.vresp.com/?fid=ac048d0e17
> >
>

Mime
View raw message