Re: TestNG & Injecting Testify services into pages
Paul, I tried the trick w/ the RequestCache; however, it blows up when I try to cast the page instance that I pick up from the cache. When I debug it, it does show that it's the same class (as is stated in the exception); however, because of the class transformations (or maybe some classloader issues) or something else I can't cast to the original class. Any other ideas of I can get a page from this cache and invoke a method on it ? @Test public void testStupidPageUnitTest() throws Exception { Object o = cache.get("stupid").getRootElement().getComponent(); // this is where the cast fails Stupid s = (Stupid)o; System.out.println("Found page : " + o); } testStupidPageUnitTest(com.troymaxventures.zadachite.pagetests.StupidPageTest) Time elapsed: 23.21 sec <<< FAILURE! *java.lang.ClassCastException: samples.pages.Stupid cannot be cast to samples.pages.Stupid* at com.troymaxventures.zadachite.pagetests.StupidPageTest.testStupidPageUnitTest(StupidPageTest.java:60) Cheers, Alex K On Tue, Feb 2, 2010 at 9:27 AM, Paul Field wrote: > akochnev wrote on 31/01/2010 11:26:53: > > >The next thing I'm trying to work out is use Testify for unit-like > > testing. The idea was that I could possibly instantiate the page class > > myself (e.g. w/o having to ask the tester to render the page), inject > the > > dependencies (using tester.injectInto(pageInstance) ) that are needed > for a > > particular method and then just invoke the method. > > The injectInto() method is designed to populate fields in a test *before* > any of the setup is done - so it doesn't really expect to work with the > @ForComponents annotations. > > You could let Tapestry do the instantiation of the page for you. I think > this will work (although it uses internal services so it might work now > but not in a future Tapestry version): > >@Inject >private RequestPageCache cache; > >public void test() { >StupidPage page = > > (StupidPage)cache.get("mypages/stupidPage").getRootElement().getComponent(); >page.myMethod(); >} > > This potentially has the advantage that all the transformations have been > done on the class - so it behaves more like the page actually will. > > Out of interest, what kind of tests need the instance of the page class? I > haven't felt the need so far so I wonder if I'm missing out on something > :-) > > Paul > > > > > > > --- > > This e-mail may contain confidential and/or privileged information. If you > are not the intended recipient (or have received this e-mail in error) > please notify the sender immediately and delete this e-mail. Any > unauthorized copying, disclosure or distribution of the material in this > e-mail is strictly forbidden. > > Please refer to http://www.db.com/en/content/eu_disclosures.htm for > additional EU corporate and regulatory disclosures. >
Re: TestNG & Injecting Testify services into pages
Paul, thanks for the help on this. I'll try it out soon. On why I'm using the page class : I guess this goes back to using POJOs for unit testing. What I mean is that in my tapestry page class I have a couple of methods (e.g. like setupRender , event handlers) which mean something special for tapestry, but still do things in the page that I want to be able to be able to test that that they do what they're supposed to. Particularly when "unit testing" the pages (that is, isolating the page as a unit, injecting mock dependencies into it), there is little to be gained by allowing tapestry to instrument the page class : all I care is that my page has a method called "foo()", and that when I call page.foo(), all the right collaborators are called and then I can assert on the postconditions of the method. If my method implementation depends on some tapestry class that is typically instrumented by the framework, I'd still probably want to have a mock implementation during the test so that I can control what it does (and doesn't go into the rabbit hole of calling a whole bunch of other T5 code) The approach that you describe w/ using the requestPageCache will probably work but it is somewhat more difficult than it needs to for a newcomer to the framework that they couldn't just instantiate the page and invoke methods on the object for testing. More accurately, as a user I can instantiate the page and invoke methods on it, but it is exceedingly hard to do the T5 IoC magic on the page (e.g. inject the dependencies) w/o jumping through some major hoops (e.g. creating a mock T5 IoC repository for each test that would make the services I want available if/when I call tester.injectInto(page). It seems like a very natural enhancement for Testify : you already have ways of declaring test specific services using @ForComponents that are injected into pages/components by the setup methods. Why not populate whatever needs to be populated w/ the same services so that injectInto works for injecting services/dependencies into the class. Alternatively, having an easy way to get to the page class from the tester (e.g. tester.getPageClass()) that does what you describe would probably do just as well. Regards, Alex K On Tue, Feb 2, 2010 at 9:27 AM, Paul Field wrote: > akochnev wrote on 31/01/2010 11:26:53: > > >The next thing I'm trying to work out is use Testify for unit-like > > testing. The idea was that I could possibly instantiate the page class > > myself (e.g. w/o having to ask the tester to render the page), inject > the > > dependencies (using tester.injectInto(pageInstance) ) that are needed > for a > > particular method and then just invoke the method. > > The injectInto() method is designed to populate fields in a test *before* > any of the setup is done - so it doesn't really expect to work with the > @ForComponents annotations. > > You could let Tapestry do the instantiation of the page for you. I think > this will work (although it uses internal services so it might work now > but not in a future Tapestry version): > >@Inject >private RequestPageCache cache; > >public void test() { >StupidPage page = > > (StupidPage)cache.get("mypages/stupidPage").getRootElement().getComponent(); >page.myMethod(); >} > > This potentially has the advantage that all the transformations have been > done on the class - so it behaves more like the page actually will. > > Out of interest, what kind of tests need the instance of the page class? I > haven't felt the need so far so I wonder if I'm missing out on something > :-) > > Paul > > > > > > > --- > > This e-mail may contain confidential and/or privileged information. If you > are not the intended recipient (or have received this e-mail in error) > please notify the sender immediately and delete this e-mail. Any > unauthorized copying, disclosure or distribution of the material in this > e-mail is strictly forbidden. > > Please refer to http://www.db.com/en/content/eu_disclosures.htm for > additional EU corporate and regulatory disclosures. >
Re: TestNG & Injecting Testify services into pages
akochnev wrote on 31/01/2010 11:26:53: >The next thing I'm trying to work out is use Testify for unit-like > testing. The idea was that I could possibly instantiate the page class > myself (e.g. w/o having to ask the tester to render the page), inject the > dependencies (using tester.injectInto(pageInstance) ) that are needed for a > particular method and then just invoke the method. The injectInto() method is designed to populate fields in a test *before* any of the setup is done - so it doesn't really expect to work with the @ForComponents annotations. You could let Tapestry do the instantiation of the page for you. I think this will work (although it uses internal services so it might work now but not in a future Tapestry version): @Inject private RequestPageCache cache; public void test() { StupidPage page = (StupidPage)cache.get("mypages/stupidPage").getRootElement().getComponent(); page.myMethod(); } This potentially has the advantage that all the transformations have been done on the class - so it behaves more like the page actually will. Out of interest, what kind of tests need the instance of the page class? I haven't felt the need so far so I wonder if I'm missing out on something :-) Paul --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.
Re: TestNG & Injecting Testify services into pages
Paul, things are working again , thanks for your help. Where I was running into trouble was that looking at the debugger, the field shows up as null up until the point the field is accessed for the first time (at which point the whole lookup of the injected field seems to occur). So, in the debugger the field was showing as null, and then the page render was failing for other reasons (e.g. for a while, incorrectly set up mocks, at other times, I was missing the .tml in the right package), but it was harder to see as the stacktrace only shows up in the rendered page (on which I was asserting). The next thing I'm trying to work out is use Testify for unit-like testing. The idea was that I could possibly instantiate the page class myself (e.g. w/o having to ask the tester to render the page), inject the dependencies (using tester.injectInto(pageInstance) ) that are needed for a particular method and then just invoke the method. I do see the SimpleObjectsForComponentStore.put(..) being called in the set up phase before the test case executes. However, using this approach, when I call tester.injectInto(page) the SimpleObjectsForComponentStore.get(..) is never called and as a result the test fails w/ a message that "No service implement the interface...". Can this be made to work in some way using Testify ? testStupidPageUnitTest(com.troymaxventures.zadachite.pagetests.StupidPageTest) Time elapsed: 136.47 sec <<< FAILURE! java.lang.RuntimeException: No service implements the interface com.troymaxventures.zadachite.services.UserRepository. at org.apache.tapestry5.ioc.internal.RegistryImpl.getService(RegistryImpl.java:575) at org.apache.tapestry5.ioc.internal.RegistryWrapper.getService(RegistryWrapper.java:58) at org.apache.tapestry5.test.PageTester.getService(PageTester.java:154) at com.formos.tapestry.testify.core.TapestryTester$FieldInjector.process(TapestryTester.java:125) at com.formos.tapestry.testify.core.TapestryTester.processField(TapestryTester.java:106) at com.formos.tapestry.testify.core.TapestryTester.processFieldsAnnotatedWith(TapestryTester.java:96) at com.formos.tapestry.testify.core.TapestryTester.injectInto(TapestryTester.java:74) at com.troymaxventures.zadachite.pagetests.StupidPageTest.testStupidPageUnitTest(StupidPageTest.java:54) Here's the test case: public class StupidPageTest extends AbstractZdTapTest { @ForComponents UserRepository userRepo; @Override protected void doSetUp() { userRepo = EasyMock.createNiceMock(UserRepository.class); System.out.println("The doSetUp() is called by TestNG"); } @Test public void testElementIsOnPage() throws Exception { ZdUser testUser = new ZdUser(new EmailAddress("f...@bar.com")); expect(userRepo.getUser(isA(EmailAddress.class))).andStubReturn(testUser); replay(userRepo); Document page = tester.renderPage("stupid"); System.out.println("Page is : " + page.toString()); Assert.assertTrue(page.toString().contains("I should be empty")); } @Test public void testStupidPageUnitTest() throws Exception { ZdUser testUser = new ZdUser(new EmailAddress("f...@bar.com")); expect(userRepo.getUser(isA(EmailAddress.class))).andStubReturn(testUser); replay(userRepo); Stupid s = new Stupid(); tester.injectInto(s); s.setupRender(); } } -- View this message in context: http://old.nabble.com/TestNG---Injecting-Testify-services-into-pages-tp27370621p27391903.html Sent from the Tapestry - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: TestNG & Injecting Testify services into pages
Going from memory when I debugged earlier this morning : I definitely saw and traced the objects marked w/ ForComponents going into the store. However, when I was rendering the page, I don't think there were any calls to get them out and inject them into the component. I definitely saw the code inspecting the test class for @Inject annotations to inject services into the test case. I'll do another debug run again tonight. The test case that I have is pretty straightforward, so I should be able to zip up an example. Regards, Alex K On Fri, Jan 29, 2010 at 1:48 PM, Paul Field wrote: > Odd - it looks like the @ForComponents objects should be created and > collected (because setup/doSetUp are called); it looks like the > setup/teardown methods are called in the right way (from the call trace in > your other email). I'm having trouble seeing what's wrong. > > At this point I would probably reach for a debugger... If you can simplify > the project to something you wouldn't mind zipping up and sending to me > I'll be happy to take a look. > > > If you want to have a go yourself, then put breakpoints on the methods of > SimpleObjectsForComponentStore - which is the service that stores the > objects that you specify with @ForComponents so you can see objects being > stored and requested. Also put a breakpoint in ThreadLocalPerTestDataStore > #cleanup() so you can see when the test ends and the data is dropped from > the SimpleObjectsForComponentsStore. > > The sequence should be: > Data collected from @ForComponents - calls to > SimpleObjectsForComponentStore#put() > Page rendering, @Inject fields accessed - calls to > SimpleObjectsForComponentStore#get() > Test complete, tearDown() called - call to ThreadLocalPerTestDataStore > #cleanup() > > As well as checking the sequence is correct, you can see what is in the > store when get is being called (and what is being requested). > > - Paul > > > akochnev wrote on 29/01/2010 13:33:00: > > > > > Paul, > >thanks for the quick response. Now, down the checklist : > > > > 1. I am extending from the testng version of the class: > > package com.troymaxventures.zadachite.pagetestsupport; > > > > > > > > import com.formos.tapestry.testify.core.TapestryTester; > > import com.formos.tapestry.testify.testng.TapestryTest; > > > > public abstract class AbstractZdTapTest extends TapestryTest { > > private static final TapestryTester SHARED_TESTER = new > > TapestryTester("foo", ZdTestAppModule.class); > > > > public AbstractZdTapTest() { > > super(SHARED_TESTER); > > } > > } > > > > 2. doSetUp() is indeed being called, I added a breakpoint and a println > : > > > >@Override > >protected void doSetUp() { > >userRepo = EasyMock.createMock(UserRepository.class); > >System.out.println("The doSetUp() is called by TestNG"); > >} > > > > The doSetUp() is called by TestNG > > Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.051 > sec > > <<< FAILURE! > > > > 3. The testng config file : > > I run the test from Maven, this is the suite file that gets generated : > > http://testng.org/testng-1.0.dtd";> > > > name="Failed suite [Command line suite]" junit="false" > annotations="JDK"> > >annotations="JDK"> > > > >name="com.troymaxventures.zadachite.pagetests.StupidPageTest"> > > > > > > > > > > > > > > > > > > > > > > > > > > 4. I added an extra test where I explicitly use the pageTester to try to > > inject the dependencies into my page. When I specify a totally bogus > package > > name ( so that Testify doesn't pick up the AppModule from my app), the > test > > fails w/ an error that it can't find my page (understandable, as I had > the > > bogus package name, so it can't find the page) when I render the page > using > > the tester; however, when I try to inject the dependencies directly into > the > > object instance, it fails that there is no instance of UserRepository . > When > > I include the full package name (so that testify picks up the > AppModule), > > the injectInto populates the service from the AppModule and not with the > > implementation that I provide in the test. When I use the > > tester.renderPage("stupid") and debug the page, I see nulls set on all > the > > services (e.g. in my example, userRepo is null), and I also see non-null > > values in some mangled names in the class (e.g. something like > > _$nonTestUserRepo) > > > > > > > > --- > > Test set: TestSuite > > > > --- > > Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.052 > sec > > <<< FAILURE! > > > testElementIsOnPage(com.troymaxventures.zadachite.pagetests.StupidPageTest) > > > Time elapsed: 0.966 sec <<< FAILURE! > > java.lang.RuntimeException: Request was not
Re: TestNG & Injecting Testify services into pages
Odd - it looks like the @ForComponents objects should be created and collected (because setup/doSetUp are called); it looks like the setup/teardown methods are called in the right way (from the call trace in your other email). I'm having trouble seeing what's wrong. At this point I would probably reach for a debugger... If you can simplify the project to something you wouldn't mind zipping up and sending to me I'll be happy to take a look. If you want to have a go yourself, then put breakpoints on the methods of SimpleObjectsForComponentStore - which is the service that stores the objects that you specify with @ForComponents so you can see objects being stored and requested. Also put a breakpoint in ThreadLocalPerTestDataStore #cleanup() so you can see when the test ends and the data is dropped from the SimpleObjectsForComponentsStore. The sequence should be: Data collected from @ForComponents - calls to SimpleObjectsForComponentStore#put() Page rendering, @Inject fields accessed - calls to SimpleObjectsForComponentStore#get() Test complete, tearDown() called - call to ThreadLocalPerTestDataStore #cleanup() As well as checking the sequence is correct, you can see what is in the store when get is being called (and what is being requested). - Paul akochnev wrote on 29/01/2010 13:33:00: > > Paul, >thanks for the quick response. Now, down the checklist : > > 1. I am extending from the testng version of the class: > package com.troymaxventures.zadachite.pagetestsupport; > > > > import com.formos.tapestry.testify.core.TapestryTester; > import com.formos.tapestry.testify.testng.TapestryTest; > > public abstract class AbstractZdTapTest extends TapestryTest { > private static final TapestryTester SHARED_TESTER = new > TapestryTester("foo", ZdTestAppModule.class); > > public AbstractZdTapTest() { > super(SHARED_TESTER); > } > } > > 2. doSetUp() is indeed being called, I added a breakpoint and a println : > >@Override >protected void doSetUp() { >userRepo = EasyMock.createMock(UserRepository.class); >System.out.println("The doSetUp() is called by TestNG"); >} > > The doSetUp() is called by TestNG > Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.051 sec > <<< FAILURE! > > 3. The testng config file : > I run the test from Maven, this is the suite file that gets generated : > http://testng.org/testng-1.0.dtd";> > name="Failed suite [Command line suite]" junit="false" annotations="JDK"> > > > > > > > > > > > > > > > > 4. I added an extra test where I explicitly use the pageTester to try to > inject the dependencies into my page. When I specify a totally bogus package > name ( so that Testify doesn't pick up the AppModule from my app), the test > fails w/ an error that it can't find my page (understandable, as I had the > bogus package name, so it can't find the page) when I render the page using > the tester; however, when I try to inject the dependencies directly into the > object instance, it fails that there is no instance of UserRepository . When > I include the full package name (so that testify picks up the AppModule), > the injectInto populates the service from the AppModule and not with the > implementation that I provide in the test. When I use the > tester.renderPage("stupid") and debug the page, I see nulls set on all the > services (e.g. in my example, userRepo is null), and I also see non-null > values in some mangled names in the class (e.g. something like > _$nonTestUserRepo) > > > --- > Test set: TestSuite > --- > Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.052 sec > <<< FAILURE! > testElementIsOnPage(com.troymaxventures.zadachite.pagetests.StupidPageTest) > Time elapsed: 0.966 sec <<< FAILURE! > java.lang.RuntimeException: Request was not handled: 'stupid' may not be a > valid page name. > at > org.apache.tapestry5.test.PageTester.renderPage(PageTester.java:177) > at > com.troymaxventures.zadachite.pagetests.StupidPageTest. > testElementIsOnPage(StupidPageTest.java:40) > > testStupidPageUnitTest(com.troymaxventures.zadachite.pagetests. > StupidPageTest) > Time elapsed: 0.01 sec <<< FAILURE! > java.lang.RuntimeException: No service implements the interface > com.troymaxventures.zadachite.services.UserRepository. > at > org.apache.tapestry5.ioc.internal.RegistryImpl. > getService(RegistryImpl.java:575) > at > org.apache.tapestry5.ioc.internal.RegistryWrapper. > getService(RegistryWrapper.java:58) > at > org.apache.tapestry5.test.PageTester.getService(PageTester.java:154) > at > com.formos.tapestry.testify.core.TapestryTester$FieldInjector. > process(
Re: TestNG & Injecting Testify services into pages
And this is the chronological listing of methods: http://old.nabble.com/file/p27372140/methods.html methods.html Below is the listing of methods in HTML, just in case the file uploaded to nabble doesn't work --- Methods run, sorted chronologically>> means before, << means afterCommand line suite(Hover the method name to see the test class name) TimeDelta (ms)SuiteconfigurationTestconfigurationClassconfigurationGroupsconfigurationMethodconfigurationTestmethodThreadInstances 10/01/29 07:56:09 0 >>processInjectAnnotation m...@9633996 10/01/29 07:56:10 1091 >>setUp m...@9633996 10/01/29 07:56:09 123 testElementIsOnPage m...@9633996 10/01/29 07:56:10 1095 <>setUp m...@9633996 10/01/29 07:56:10 1092 testStupidPageUnitTest m...@9633996 10/01/29 07:56:10 1095 < > Paul, >thanks for the quick response. Now, down the checklist : > > 1. I am extending from the testng version of the class: > package com.troymaxventures.zadachite.pagetestsupport; > > > > import com.formos.tapestry.testify.core.TapestryTester; > import com.formos.tapestry.testify.testng.TapestryTest; > > public abstract class AbstractZdTapTest extends TapestryTest { > private static final TapestryTester SHARED_TESTER = new > TapestryTester("foo", ZdTestAppModule.class); > > public AbstractZdTapTest() { > super(SHARED_TESTER); > } > } > > 2. doSetUp() is indeed being called, I added a breakpoint and a println : > >@Override >protected void doSetUp() { >userRepo = EasyMock.createMock(UserRepository.class); >System.out.println("The doSetUp() is called by TestNG"); >} > > The doSetUp() is called by TestNG > Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.051 sec > <<< FAILURE! > > 3. The testng config file : > I run the test from Maven, this is the suite file that gets generated : > http://testng.org/testng-1.0.dtd";> > name="Failed suite [Command line suite]" junit="false" annotations="JDK"> > > >name="com.troymaxventures.zadachite.pagetests.StupidPageTest"> > > > > > > > > > > > > > 4. I added an extra test where I explicitly use the pageTester to try to > inject the dependencies into my page. When I specify a totally bogus > package name ( so that Testify doesn't pick up the AppModule from my app), > the test fails w/ an error that it can't find my page (understandable, as > I had the bogus package name, so it can't find the page) when I render the > page using the tester; however, when I try to inject the dependencies > directly into the object instance, it fails that there is no instance of > UserRepository . When I include the full package name (so that testify > picks up the AppModule), the injectInto populates the service from the > AppModule and not with the implementation that I provide in the test. When > I use the tester.renderPage("stupid") and debug the page, I see nulls set > on all the services (e.g. in my example, userRepo is null), and I also see > non-null values in some mangled names in the class (e.g. something like > _$nonTestUserRepo) > > > --- > Test set: TestSuite > --- > Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.052 sec > <<< FAILURE! > testElementIsOnPage(com.troymaxventures.zadachite.pagetests.StupidPageTest) > Time elapsed: 0.966 sec <<< FAILURE! > java.lang.RuntimeException: Request was not handled: 'stupid' may not be a > valid page name. > at > org.apache.tapestry5.test.PageTester.renderPage(PageTester.java:177) > at > com.troymaxventures.zadachite.pagetests.StupidPageTest.testElementIsOnPage(StupidPageTest.java:40) > > testStupidPageUnitTest(com.troymaxventures.zadachite.pagetests.StupidPageTest) > > Time elapsed: 0.01 sec <<< FAILURE! > java.lang.RuntimeException: No service implements the interface > com.troymaxventures.zadachite.services.UserRepository. > at > org.apache.tapestry5.ioc.internal.RegistryImpl.getService(RegistryImpl.java:575) > at > org.apache.tapestry5.ioc.internal.RegistryWrapper.getService(RegistryWrapper.java:58) > at > org.apache.tapestry5.test.PageTester.getService(PageTester.java:154) > at > com.formos.tapestry.testify.core.TapestryTester$FieldInjector.process(TapestryTester.java:125) > at > com.formos.tapestry.testify.core.TapestryTester.processField(TapestryTester.java:106) > at > com.formos.tapestry.testify.core.TapestryTester.processFieldsAnnotatedWith(TapestryTester.java:96) > at > com.formos.tapestry.testify.core.TapestryTester.inj
Re: TestNG & Injecting Testify services into pages
Paul, thanks for the quick response. Now, down the checklist : 1. I am extending from the testng version of the class: package com.troymaxventures.zadachite.pagetestsupport; import com.formos.tapestry.testify.core.TapestryTester; import com.formos.tapestry.testify.testng.TapestryTest; public abstract class AbstractZdTapTest extends TapestryTest { private static final TapestryTester SHARED_TESTER = new TapestryTester("foo", ZdTestAppModule.class); public AbstractZdTapTest() { super(SHARED_TESTER); } } 2. doSetUp() is indeed being called, I added a breakpoint and a println : @Override protected void doSetUp() { userRepo = EasyMock.createMock(UserRepository.class); System.out.println("The doSetUp() is called by TestNG"); } The doSetUp() is called by TestNG Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.051 sec <<< FAILURE! 3. The testng config file : I run the test from Maven, this is the suite file that gets generated : http://testng.org/testng-1.0.dtd";> 4. I added an extra test where I explicitly use the pageTester to try to inject the dependencies into my page. When I specify a totally bogus package name ( so that Testify doesn't pick up the AppModule from my app), the test fails w/ an error that it can't find my page (understandable, as I had the bogus package name, so it can't find the page) when I render the page using the tester; however, when I try to inject the dependencies directly into the object instance, it fails that there is no instance of UserRepository . When I include the full package name (so that testify picks up the AppModule), the injectInto populates the service from the AppModule and not with the implementation that I provide in the test. When I use the tester.renderPage("stupid") and debug the page, I see nulls set on all the services (e.g. in my example, userRepo is null), and I also see non-null values in some mangled names in the class (e.g. something like _$nonTestUserRepo) --- Test set: TestSuite --- Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 5.052 sec <<< FAILURE! testElementIsOnPage(com.troymaxventures.zadachite.pagetests.StupidPageTest) Time elapsed: 0.966 sec <<< FAILURE! java.lang.RuntimeException: Request was not handled: 'stupid' may not be a valid page name. at org.apache.tapestry5.test.PageTester.renderPage(PageTester.java:177) at com.troymaxventures.zadachite.pagetests.StupidPageTest.testElementIsOnPage(StupidPageTest.java:40) testStupidPageUnitTest(com.troymaxventures.zadachite.pagetests.StupidPageTest) Time elapsed: 0.01 sec <<< FAILURE! java.lang.RuntimeException: No service implements the interface com.troymaxventures.zadachite.services.UserRepository. at org.apache.tapestry5.ioc.internal.RegistryImpl.getService(RegistryImpl.java:575) at org.apache.tapestry5.ioc.internal.RegistryWrapper.getService(RegistryWrapper.java:58) at org.apache.tapestry5.test.PageTester.getService(PageTester.java:154) at com.formos.tapestry.testify.core.TapestryTester$FieldInjector.process(TapestryTester.java:125) at com.formos.tapestry.testify.core.TapestryTester.processField(TapestryTester.java:106) at com.formos.tapestry.testify.core.TapestryTester.processFieldsAnnotatedWith(TapestryTester.java:96) at com.formos.tapestry.testify.core.TapestryTester.injectInto(TapestryTester.java:74) at com.troymaxventures.zadachite.pagetests.StupidPageTest.testStupidPageUnitTest(StupidPageTest.java:53) The superclass w/ a bogus package name: import com.formos.tapestry.testify.core.TapestryTester; import com.formos.tapestry.testify.testng.TapestryTest; public abstract class AbstractZdTapTest extends TapestryTest { private static final TapestryTester SHARED_TESTER = new TapestryTester("foo", ZdTestAppModule.class); public AbstractZdTapTest() { super(SHARED_TESTER); } } import com.formos.tapestry.testify.core.ForComponents; import com.troymaxventures.zadachite.model.EmailAddress; import com.troymaxventures.zadachite.model.UserRegistration; import com.troymaxventures.zadachite.model.ZdUser; import com.troymaxventures.zadachite.pages.Stupid; import com.troymaxventures.zadachite.pagetestsupport.AbstractZdTapTest; import com.troymaxventures.zadachite.services.UserRepository; import org.apache.tapestry5.dom.Document; import org.easymock.EasyMock; import org.testng.Assert; import org.testng.annotations.Test; import static org.easymock.EasyMock.*; /** * * @author polrtex */ public class StupidPageTest extends AbstractZdTapTest { @ForComponents UserRepository userRepo; @Override protected void doSetUp() { userRepo = EasyMock.c
Re: TestNG & Injecting Testify services into pages
>From a quick scan, I can't see anything obviously wrong with the code you've written. Just in case, make sure you are using the correct base class (com.formos.testify.testng.TapestryTest) as there are several base classes with the same simple name. The next thing is probably to check that the various setup methods are being called. Can you put a print statement into doSetUp() and check it's actually being called? This will let us see whether the setup isn't being called, or the @ForComponents processing isn't working properly. I suspect the doSetUp()isn't being called and that's going to be a TestNG thing: it should be calling TapestryTest#setUp() method... Can you check the TestNG output reports - I seem to remember that one of them outputs the sequence of setup methods and tests? If you're still stuck can you also send the testng configuration (xml) file? Let me know what you find. - Paul akochnev wrote on 29/01/2010 11:24:01: > > I'm running into trouble with using services declared inside of a Testify > TestNG test case with @ForComponents into my pages - when I ask the tester > to render a page, the services that were supposed to be injected, are null. > Any tips on what I'm doing wrong ? > > > Here is the sample code: > > public class StupidPageTest extends AbstractZdTapTest { >@ForComponents >private UserRepository userRepo; > > >@Override >protected void doSetUp() { >userRepo = EasyMock.createMock(UserRepository.class); >} > > >@Test >public void testElementIsOnPage() throws Exception { > > expect(userRepo.userRegistered((EmailAddress)anyObject())). > andStubReturn(Boolean.FALSE); >ZdUser testUser = new ZdUser(new EmailAddress("f...@bar.com"));; > > expect(userRepo.registerUser(isA(UserRegistration.class))). > andStubReturn(testUser); >replay(userRepo); >Document page = tester.renderPage("stupid"); >System.out.println("Rendered page: " + page.toString()); > >} > } > > public abstract class AbstractZdTapTest extends TapestryTest { > private static final TapestryTester SHARED_TESTER = new > TapestryTester("com.troymaxventures.zadachite", > ZdTestAppModule.class,AppModule.class); > > public AbstractZdTapTest() { > super(SHARED_TESTER); > } > } > > public abstract class AbstractZdTapTest extends TapestryTest { > private static final TapestryTester SHARED_TESTER = new > TapestryTester("com.troymaxventures.zadachite", ZdTestAppModule.class); > > public AbstractZdTapTest() { > super(SHARED_TESTER); > } > } > > public class ZdTestAppModule { > > /** > * Ensure that there are valid HTTP request/response objects in the > test, otherwise the ACEGI integration tends to blow up. > */ > public static void > contributeRequestHandler(OrderedConfiguration config, final > RequestGlobals requestGlobals) { > RequestFilter filter = new RequestFilter() { > > @Override > public boolean service(Request request, Response response, > RequestHandler handler) throws IOException { > > requestGlobals.storeServletRequestResponse(EasyMock. > createMock(HttpServletRequest.class), > EasyMock.createMock(HttpServletResponse.class)); > return handler.service(request, response); > } > }; > config.add("EnsureNonNullHttpRequestAndResponse", filter, > "before:*"); > } > } > > public class Stupid { > @Inject > private UserRepository userRepo; > void setupRender() throws StorageException { > // the userRepo is null here during the test > userRepo.getUser(new EmailAddress("f...@bar.com")); > } > } > > > -- > View this message in context: http://old.nabble.com/TestNG--- > Injecting-Testify-services-into-pages-tp27370621p27370621.html > Sent from the Tapestry - User mailing list archive at Nabble.com. > > > - > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > For additional commands, e-mail: users-h...@tapestry.apache.org > --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.