You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by George Christman <gc...@cardaddy.com> on 2014/01/21 18:07:31 UTC

How do you unit test services with dependent services

Hello, we are trying to unit test our services, but our services contain
other injected services. I'm wondering how you test injected services. Is
there a configuration I'm missing?

-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: How do you unit test services with dependent services

Posted by "Nourredine K." <no...@gmail.com>.
Hi,

Just use the PageTester#getService<http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html#getService%28java.lang.Class%29>method
in your unit tests.




2014/1/21 George Christman <gc...@cardaddy.com>

> Hello, we are trying to unit test our services, but our services contain
> other injected services. I'm wondering how you test injected services. Is
> there a configuration I'm missing?
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>

Re: How do you unit test services with dependent services

Posted by Lance Java <la...@googlemail.com>.
You can use

IOCUtilities.addDefaultModules(RegistryBuilder)

To scan the classpath for META-INF entries.
On 21 Jan 2014 19:47, "George Christman" <gc...@cardaddy.com> wrote:

> and that is the easiest way to do it ugh lol
>
>
> On Tue, Jan 21, 2014 at 2:30 PM, Dragan Sahpaski
> <dr...@gmail.com>wrote:
>
> > You have to manually add ALL the tapestry IOC modules you're using (in
> this
> > case the tapestry-security module
> > org.tynamo.security.services.SecurityModule), because you're starting
> only
> > the Registry and not the entire webapp.
> >
> > Cheers,
> > Dragan Sahpaski
> >
> >
> > On Tue, Jan 21, 2014 at 8:22 PM, George Christman
> > <gc...@cardaddy.com>wrote:
> >
> > > Dmitry, I'm very confused. I use constructor injection in my services
> > which
> > > I always thought was the correct way to do it based on the tap docs.
> > >
> > > I have the following test class where I'm trying to use a service.
> > >
> > > public class TimeSheetServiceTest {
> > >
> > >     protected static TimeSheetService timeSheetService;
> > >
> > >     @BeforeClass
> > >     public static void setup() {
> > >         Registry registry;
> > >         RegistryBuilder builder = new RegistryBuilder();
> > >         builder.add(AppModule.class);
> > >         registry = builder.build();
> > >         registry.performRegistryStartup();
> > >         timeSheetService = registry.getService(TimeSheetService.class);
> > >     }
> > >
> > >     @Test
> > >     public void testService() {
> > >         int result =
> > >
> >
> timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
> > >         System.out.println("result " + result);
> > >     }
> > >
> > > }
> > >
> > > TimeSheetService injects another service called UserInfoService
> userInfo
> > > like so,
> > >
> > > public class TimeSheetServiceImpl implements TimeSheetService {
> > >
> > >     public TimeSheetServiceImpl(UserInfoService userInfo) {
> > >         this.userInfo = userInfo;
> > >     }
> > >
> > > }
> > >
> > > When I try running my test class, I get the following exception.
> > >
> > > <?xml version="1.0" encoding="UTF-8"?>
> > >
> > > <!-- Generated by org.testng.reporters.JUnitReportReporter -->
> > > -<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58
> GMT"
> > > failures="1" tests="1"
> > > name="org.domain.etss.services.form.TimeSheetServiceTest"
> > > hostname="hri185169">
> > > <!-- org.domain.etss.services.form.TimeSheetServiceTest -->
> > > -<testcase time="0.000" name="testService"
> > >
> classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
> > > message="Contribution
> > >
> > >
> >
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> > > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> > > 'SecurityConfiguration', which does not exist."
> > > type="java.lang.IllegalArgumentException">
> > > <![CDATA[java.lang.IllegalArgumentException: Contribution
> > >
> > >
> >
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> > > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> > > 'SecurityConfiguration', which does not exist. at
> > >
> > >
> >
> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
> > > at
> > >
> > >
> >
> org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
> > > at
> > org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
> > > at
> > >
> > >
> >
> org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> > >
> > >
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> > > at
> > >
> > >
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > > at java.lang.reflect.Method.invoke(Method.java:601) at
> > >
> > >
> >
> org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
> > > at
> > org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
> > > at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
> at
> > > org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) at
> > >
> > >
> >
> org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
> > > at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
> at
> > > org.testng.TestRunner.privateRun(TestRunner.java:768) at
> > > org.testng.TestRunner.run(TestRunner.java:617) at
> > > org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
> > > org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
> > > org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
> > > org.testng.SuiteRunner.run(SuiteRunner.java:240) at
> > > org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
> > > org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
> > > org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
> > > org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
> > > org.testng.TestNG.run(TestNG.java:1025) at
> > >
> >
> org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
> > > at
> > >
> > >
> >
> org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
> > > at
> > >
> > >
> >
> org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> > >
> > >
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> > > at
> > >
> > >
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > > at java.lang.reflect.Method.invoke(Method.java:601) at
> > >
> > >
> >
> org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
> > > at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
> > >
> > >
> >
> org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
> > > at
> > >
> > >
> >
> org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
> > > at
> > org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
> > > ]]>
> > > </failure></testcase>
> > > <!-- testService -->
> > > </testsuite>
> > >
> > > From this line
> > >
> > > public static void
> > > contributeSecurityConfiguration(Configuration<SecurityFilterChain>
> > > configuration,
> > >
> > > SecurityFilterChainFactory factory) {
> > >
> > >
> >
> configuration.add(factory.createChain("/employee/**").add(factory.roles(),
> > > "employee").build());
> > >         configuration.add(factory.createChain("/").add(factory.roles(),
> > > "user").build());
> > >     }
> > >
> > > What am I missing?
> > >
> > >
> > > On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> > > >wrote:
> > >
> > > > Right, this is for integration testing. I use mocking too, but rarely
> > --
> > > my
> > > > tests are 80% integration ones and involve DB (the same as in
> > > production).
> > > > For mocks I have to use constructor injection also, and this is the
> > only
> > > > reason why I use constructor injections.
> > > > The code looks ugly in this cases, though, when you have more than 5
> > > > dependencies per service. And it's also a tedious task when you want
> to
> > > add
> > > > another dependency to the service, because you have to update all
> test
> > > > clients also. That's why I prefer @Inject.
> > > >
> > > > It would be nice to have some api to override, decorate, and advise
> > some
> > > > services on existing (built) registry instance right in the test
> > method.
> > > > Maybe (temporarily) replace some service with a mock. So that I won't
> > > have
> > > > to build new module just to override one service for one test case,
> > > because
> > > > it requires additional setup. Just a thoughts.
> > > >
> > > >
> > > > On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
> > > > <dr...@gmail.com>wrote:
> > > >
> > > > > I agree with Dimitry but thats more for integration like testing.
> > > > > For basic unit testing of services methods (usually we unit test a
> > > single
> > > > > method per test) we mock the dependencies (the injected services)
> and
> > > > pass
> > > > > the mocks through the constructor of the service implementation
> class
> > > > under
> > > > > test. That's why we prefer constructor based injection.
> > > > >
> > > > > If we need to mock methods in the service that's being bested than
> we
> > > > > usually use Spy in Spock or the equivalent feature in other mock
> > > > > frameworks.
> > > > >
> > > > > Cheers,
> > > > > Dragan Sahpaski
> > > > >
> > > > >
> > > > > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <
> > dmitry.gusev@gmail.com
> > > > > >wrote:
> > > > >
> > > > > > I usually create base class where I construct registry instance,
> > > then I
> > > > > use
> > > > > > registry.getService(Intf.class) when I need an instance of a
> > service.
> > > > > >
> > > > > > Like here:
> > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> > > > > >
> > > > > >
> > > > > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > > > > > <gc...@cardaddy.com>wrote:
> > > > > >
> > > > > > > Hello, we are trying to unit test our services, but our
> services
> > > > > contain
> > > > > > > other injected services. I'm wondering how you test injected
> > > > services.
> > > > > Is
> > > > > > > there a configuration I'm missing?
> > > > > > >
> > > > > > > --
> > > > > > > George Christman
> > > > > > > www.CarDaddy.com
> > > > > > > P.O. Box 735
> > > > > > > Johnstown, New York
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > --
> > > > > > Dmitry Gusev
> > > > > >
> > > > > > AnjLab Team
> > > > > > http://anjlab.com
> > > > > >
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > Dmitry Gusev
> > > >
> > > > AnjLab Team
> > > > http://anjlab.com
> > > >
> > >
> > >
> > >
> > > --
> > > George Christman
> > > www.CarDaddy.com
> > > P.O. Box 735
> > > Johnstown, New York
> > >
> >
>
>
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>

Re: How do you unit test services with dependent services

Posted by Lance Java <la...@googlemail.com>.
I think it would be easy enough to create a TapestryJUnit4ClassRunner which
is similar to SpringJUnit4ClassRunner.

eg:

@RunWith(TapestryJUnit4ClassRunner.class)
@Modules({SecurityModule.class, HibernateModule.class, MyTestModule.class})
@ModuleDefs({SpringModuleDef.class})
public class MyIOCTest {
   public static class MyTestModule {
      public static Foo buildFoo() { return new FooImmpl(); }
   }

   @Inject
   private Foo foo;

   public void testFoo() {
      Assert.assertNotNull(fo.doStuff());
   }
}

Re: How do you unit test services with dependent services

Posted by Dragan Sahpaski <dr...@gmail.com>.
Alternatively use the @SubModule in your AppModule which is not needed for
a webapp because when starting the tapestry filter, tapestry autoloads the
ioc modules for all jars on the classpath. This is very well documented
here http://tapestry.apache.org/autoloading-modules.html

You can see the code that does this in TapestryAppInitializer.java which
uses IOCUtilities.addDefaultModules to add the ioc modules (which you can
try also if you want to avoid specifying each module manually).

Cheers,
Dragan Sahpaski


On Tue, Jan 21, 2014 at 9:04 PM, Dmitry Gusev <dm...@gmail.com>wrote:

> As Dragan said, you have to add all modules manually.
> In the thread I've posted a link to above you can find some references,
> like here:
>
>
> https://gist.github.com/dmitrygusev/6672859#file-baseintegrationtest-java-L11-L18
>
> Notice, the class also extends AbstractShiroTest, because some additional
> setup required for shiro and unit testing.
>
>
> On Tue, Jan 21, 2014 at 11:59 PM, George Christman
> <gc...@cardaddy.com>wrote:
>
> > Am I going about this all the wrong way? Am I using the services
> correctly?
> > I never see in any example test code where you guys are having to add all
> > the modules. Any suggestions?
> >
> >
> > On Tue, Jan 21, 2014 at 2:47 PM, George Christman
> > <gc...@cardaddy.com>wrote:
> >
> > > and that is the easiest way to do it ugh lol
> > >
> > >
> > > On Tue, Jan 21, 2014 at 2:30 PM, Dragan Sahpaski <
> > > dragan.sahpaski@gmail.com> wrote:
> > >
> > >> You have to manually add ALL the tapestry IOC modules you're using (in
> > >> this
> > >> case the tapestry-security module
> > >> org.tynamo.security.services.SecurityModule), because you're starting
> > only
> > >> the Registry and not the entire webapp.
> > >>
> > >> Cheers,
> > >> Dragan Sahpaski
> > >>
> > >>
> > >> On Tue, Jan 21, 2014 at 8:22 PM, George Christman
> > >> <gc...@cardaddy.com>wrote:
> > >>
> > >> > Dmitry, I'm very confused. I use constructor injection in my
> services
> > >> which
> > >> > I always thought was the correct way to do it based on the tap docs.
> > >> >
> > >> > I have the following test class where I'm trying to use a service.
> > >> >
> > >> > public class TimeSheetServiceTest {
> > >> >
> > >> >     protected static TimeSheetService timeSheetService;
> > >> >
> > >> >     @BeforeClass
> > >> >     public static void setup() {
> > >> >         Registry registry;
> > >> >         RegistryBuilder builder = new RegistryBuilder();
> > >> >         builder.add(AppModule.class);
> > >> >         registry = builder.build();
> > >> >         registry.performRegistryStartup();
> > >> >         timeSheetService =
> > registry.getService(TimeSheetService.class);
> > >> >     }
> > >> >
> > >> >     @Test
> > >> >     public void testService() {
> > >> >         int result =
> > >> >
> > >>
> >
> timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
> > >> >         System.out.println("result " + result);
> > >> >     }
> > >> >
> > >> > }
> > >> >
> > >> > TimeSheetService injects another service called UserInfoService
> > userInfo
> > >> > like so,
> > >> >
> > >> > public class TimeSheetServiceImpl implements TimeSheetService {
> > >> >
> > >> >     public TimeSheetServiceImpl(UserInfoService userInfo) {
> > >> >         this.userInfo = userInfo;
> > >> >     }
> > >> >
> > >> > }
> > >> >
> > >> > When I try running my test class, I get the following exception.
> > >> >
> > >> > <?xml version="1.0" encoding="UTF-8"?>
> > >> >
> > >> > <!-- Generated by org.testng.reporters.JUnitReportReporter -->
> > >> > -<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58
> > GMT"
> > >> > failures="1" tests="1"
> > >> > name="org.domain.etss.services.form.TimeSheetServiceTest"
> > >> > hostname="hri185169">
> > >> > <!-- org.domain.etss.services.form.TimeSheetServiceTest -->
> > >> > -<testcase time="0.000" name="testService"
> > >> >
> > classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
> > >> > message="Contribution
> > >> >
> > >> >
> > >>
> >
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> > >> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> > >> > 'SecurityConfiguration', which does not exist."
> > >> > type="java.lang.IllegalArgumentException">
> > >> > <![CDATA[java.lang.IllegalArgumentException: Contribution
> > >> >
> > >> >
> > >>
> >
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> > >> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> > >> > 'SecurityConfiguration', which does not exist. at
> > >> >
> > >> >
> > >>
> >
> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
> > >> > at
> > >>
> org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
> > >> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> > >> >
> > >> >
> > >>
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > >> > at java.lang.reflect.Method.invoke(Method.java:601) at
> > >> >
> > >> >
> > >>
> >
> org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
> > >> > at
> > >>
> org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
> > >> > at
> org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
> > at
> > >> > org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
> at
> > >> >
> > >> >
> > >>
> >
> org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
> > >> > at
> org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
> > >> at
> > >> > org.testng.TestRunner.privateRun(TestRunner.java:768) at
> > >> > org.testng.TestRunner.run(TestRunner.java:617) at
> > >> > org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
> > >> > org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
> > >> > org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
> > >> > org.testng.SuiteRunner.run(SuiteRunner.java:240) at
> > >> > org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
> > >> > org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
> > >> > org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
> > >> > org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
> > >> > org.testng.TestNG.run(TestNG.java:1025) at
> > >> >
> > >>
> >
> org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
> > >> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> > >> >
> > >> >
> > >>
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > >> > at java.lang.reflect.Method.invoke(Method.java:601) at
> > >> >
> > >> >
> > >>
> >
> org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
> > >> > at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
> > >> >
> > >> >
> > >>
> >
> org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
> > >> > at
> > >> >
> > >> >
> > >>
> >
> org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
> > >> > at
> > >>
> org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
> > >> > ]]>
> > >> > </failure></testcase>
> > >> > <!-- testService -->
> > >> > </testsuite>
> > >> >
> > >> > From this line
> > >> >
> > >> > public static void
> > >> > contributeSecurityConfiguration(Configuration<SecurityFilterChain>
> > >> > configuration,
> > >> >
> > >> > SecurityFilterChainFactory factory) {
> > >> >
> > >> >
> > >>
> >
> configuration.add(factory.createChain("/employee/**").add(factory.roles(),
> > >> > "employee").build());
> > >> >
> > configuration.add(factory.createChain("/").add(factory.roles(),
> > >> > "user").build());
> > >> >     }
> > >> >
> > >> > What am I missing?
> > >> >
> > >> >
> > >> > On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <
> dmitry.gusev@gmail.com
> > >> > >wrote:
> > >> >
> > >> > > Right, this is for integration testing. I use mocking too, but
> > rarely
> > >> --
> > >> > my
> > >> > > tests are 80% integration ones and involve DB (the same as in
> > >> > production).
> > >> > > For mocks I have to use constructor injection also, and this is
> the
> > >> only
> > >> > > reason why I use constructor injections.
> > >> > > The code looks ugly in this cases, though, when you have more
> than 5
> > >> > > dependencies per service. And it's also a tedious task when you
> want
> > >> to
> > >> > add
> > >> > > another dependency to the service, because you have to update all
> > test
> > >> > > clients also. That's why I prefer @Inject.
> > >> > >
> > >> > > It would be nice to have some api to override, decorate, and
> advise
> > >> some
> > >> > > services on existing (built) registry instance right in the test
> > >> method.
> > >> > > Maybe (temporarily) replace some service with a mock. So that I
> > won't
> > >> > have
> > >> > > to build new module just to override one service for one test
> case,
> > >> > because
> > >> > > it requires additional setup. Just a thoughts.
> > >> > >
> > >> > >
> > >> > > On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
> > >> > > <dr...@gmail.com>wrote:
> > >> > >
> > >> > > > I agree with Dimitry but thats more for integration like
> testing.
> > >> > > > For basic unit testing of services methods (usually we unit
> test a
> > >> > single
> > >> > > > method per test) we mock the dependencies (the injected
> services)
> > >> and
> > >> > > pass
> > >> > > > the mocks through the constructor of the service implementation
> > >> class
> > >> > > under
> > >> > > > test. That's why we prefer constructor based injection.
> > >> > > >
> > >> > > > If we need to mock methods in the service that's being bested
> than
> > >> we
> > >> > > > usually use Spy in Spock or the equivalent feature in other mock
> > >> > > > frameworks.
> > >> > > >
> > >> > > > Cheers,
> > >> > > > Dragan Sahpaski
> > >> > > >
> > >> > > >
> > >> > > > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <
> > >> dmitry.gusev@gmail.com
> > >> > > > >wrote:
> > >> > > >
> > >> > > > > I usually create base class where I construct registry
> instance,
> > >> > then I
> > >> > > > use
> > >> > > > > registry.getService(Intf.class) when I need an instance of a
> > >> service.
> > >> > > > >
> > >> > > > > Like here:
> > >> > > > >
> > >> > > > >
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> > >> > > > >
> > >> > > > >
> > >> > > > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > >> > > > > <gc...@cardaddy.com>wrote:
> > >> > > > >
> > >> > > > > > Hello, we are trying to unit test our services, but our
> > services
> > >> > > > contain
> > >> > > > > > other injected services. I'm wondering how you test injected
> > >> > > services.
> > >> > > > Is
> > >> > > > > > there a configuration I'm missing?
> > >> > > > > >
> > >> > > > > > --
> > >> > > > > > George Christman
> > >> > > > > > www.CarDaddy.com
> > >> > > > > > P.O. Box 735
> > >> > > > > > Johnstown, New York
> > >> > > > > >
> > >> > > > >
> > >> > > > >
> > >> > > > >
> > >> > > > > --
> > >> > > > > Dmitry Gusev
> > >> > > > >
> > >> > > > > AnjLab Team
> > >> > > > > http://anjlab.com
> > >> > > > >
> > >> > > >
> > >> > >
> > >> > >
> > >> > >
> > >> > > --
> > >> > > Dmitry Gusev
> > >> > >
> > >> > > AnjLab Team
> > >> > > http://anjlab.com
> > >> > >
> > >> >
> > >> >
> > >> >
> > >> > --
> > >> > George Christman
> > >> > www.CarDaddy.com
> > >> > P.O. Box 735
> > >> > Johnstown, New York
> > >> >
> > >>
> > >
> > >
> > >
> > > --
> > > George Christman
> > > www.CarDaddy.com
> > > P.O. Box 735
> > > Johnstown, New York
> > >
> > >
> >
> >
> > --
> > George Christman
> > www.CarDaddy.com
> > P.O. Box 735
> > Johnstown, New York
> >
>
>
>
> --
> Dmitry Gusev
>
> AnjLab Team
> http://anjlab.com
>

Re: How do you unit test services with dependent services

Posted by Dmitry Gusev <dm...@gmail.com>.
As Dragan said, you have to add all modules manually.
In the thread I've posted a link to above you can find some references,
like here:

https://gist.github.com/dmitrygusev/6672859#file-baseintegrationtest-java-L11-L18

Notice, the class also extends AbstractShiroTest, because some additional
setup required for shiro and unit testing.


On Tue, Jan 21, 2014 at 11:59 PM, George Christman
<gc...@cardaddy.com>wrote:

> Am I going about this all the wrong way? Am I using the services correctly?
> I never see in any example test code where you guys are having to add all
> the modules. Any suggestions?
>
>
> On Tue, Jan 21, 2014 at 2:47 PM, George Christman
> <gc...@cardaddy.com>wrote:
>
> > and that is the easiest way to do it ugh lol
> >
> >
> > On Tue, Jan 21, 2014 at 2:30 PM, Dragan Sahpaski <
> > dragan.sahpaski@gmail.com> wrote:
> >
> >> You have to manually add ALL the tapestry IOC modules you're using (in
> >> this
> >> case the tapestry-security module
> >> org.tynamo.security.services.SecurityModule), because you're starting
> only
> >> the Registry and not the entire webapp.
> >>
> >> Cheers,
> >> Dragan Sahpaski
> >>
> >>
> >> On Tue, Jan 21, 2014 at 8:22 PM, George Christman
> >> <gc...@cardaddy.com>wrote:
> >>
> >> > Dmitry, I'm very confused. I use constructor injection in my services
> >> which
> >> > I always thought was the correct way to do it based on the tap docs.
> >> >
> >> > I have the following test class where I'm trying to use a service.
> >> >
> >> > public class TimeSheetServiceTest {
> >> >
> >> >     protected static TimeSheetService timeSheetService;
> >> >
> >> >     @BeforeClass
> >> >     public static void setup() {
> >> >         Registry registry;
> >> >         RegistryBuilder builder = new RegistryBuilder();
> >> >         builder.add(AppModule.class);
> >> >         registry = builder.build();
> >> >         registry.performRegistryStartup();
> >> >         timeSheetService =
> registry.getService(TimeSheetService.class);
> >> >     }
> >> >
> >> >     @Test
> >> >     public void testService() {
> >> >         int result =
> >> >
> >>
> timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
> >> >         System.out.println("result " + result);
> >> >     }
> >> >
> >> > }
> >> >
> >> > TimeSheetService injects another service called UserInfoService
> userInfo
> >> > like so,
> >> >
> >> > public class TimeSheetServiceImpl implements TimeSheetService {
> >> >
> >> >     public TimeSheetServiceImpl(UserInfoService userInfo) {
> >> >         this.userInfo = userInfo;
> >> >     }
> >> >
> >> > }
> >> >
> >> > When I try running my test class, I get the following exception.
> >> >
> >> > <?xml version="1.0" encoding="UTF-8"?>
> >> >
> >> > <!-- Generated by org.testng.reporters.JUnitReportReporter -->
> >> > -<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58
> GMT"
> >> > failures="1" tests="1"
> >> > name="org.domain.etss.services.form.TimeSheetServiceTest"
> >> > hostname="hri185169">
> >> > <!-- org.domain.etss.services.form.TimeSheetServiceTest -->
> >> > -<testcase time="0.000" name="testService"
> >> >
> classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
> >> > message="Contribution
> >> >
> >> >
> >>
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> >> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> >> > 'SecurityConfiguration', which does not exist."
> >> > type="java.lang.IllegalArgumentException">
> >> > <![CDATA[java.lang.IllegalArgumentException: Contribution
> >> >
> >> >
> >>
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> >> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> >> > 'SecurityConfiguration', which does not exist. at
> >> >
> >> >
> >>
> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
> >> > at
> >> >
> >> >
> >>
> org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
> >> > at
> >> org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
> >> > at
> >> >
> >> >
> >>
> org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
> >> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> >> >
> >> >
> >>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> >> > at
> >> >
> >> >
> >>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> >> > at java.lang.reflect.Method.invoke(Method.java:601) at
> >> >
> >> >
> >>
> org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
> >> > at
> >> org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
> >> > at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
> at
> >> > org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) at
> >> >
> >> >
> >>
> org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
> >> > at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
> >> at
> >> > org.testng.TestRunner.privateRun(TestRunner.java:768) at
> >> > org.testng.TestRunner.run(TestRunner.java:617) at
> >> > org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
> >> > org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
> >> > org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
> >> > org.testng.SuiteRunner.run(SuiteRunner.java:240) at
> >> > org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
> >> > org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
> >> > org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
> >> > org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
> >> > org.testng.TestNG.run(TestNG.java:1025) at
> >> >
> >>
> org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
> >> > at
> >> >
> >> >
> >>
> org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
> >> > at
> >> >
> >> >
> >>
> org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
> >> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> >> >
> >> >
> >>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> >> > at
> >> >
> >> >
> >>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> >> > at java.lang.reflect.Method.invoke(Method.java:601) at
> >> >
> >> >
> >>
> org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
> >> > at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
> >> >
> >> >
> >>
> org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
> >> > at
> >> >
> >> >
> >>
> org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
> >> > at
> >> org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
> >> > ]]>
> >> > </failure></testcase>
> >> > <!-- testService -->
> >> > </testsuite>
> >> >
> >> > From this line
> >> >
> >> > public static void
> >> > contributeSecurityConfiguration(Configuration<SecurityFilterChain>
> >> > configuration,
> >> >
> >> > SecurityFilterChainFactory factory) {
> >> >
> >> >
> >>
> configuration.add(factory.createChain("/employee/**").add(factory.roles(),
> >> > "employee").build());
> >> >
> configuration.add(factory.createChain("/").add(factory.roles(),
> >> > "user").build());
> >> >     }
> >> >
> >> > What am I missing?
> >> >
> >> >
> >> > On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> >> > >wrote:
> >> >
> >> > > Right, this is for integration testing. I use mocking too, but
> rarely
> >> --
> >> > my
> >> > > tests are 80% integration ones and involve DB (the same as in
> >> > production).
> >> > > For mocks I have to use constructor injection also, and this is the
> >> only
> >> > > reason why I use constructor injections.
> >> > > The code looks ugly in this cases, though, when you have more than 5
> >> > > dependencies per service. And it's also a tedious task when you want
> >> to
> >> > add
> >> > > another dependency to the service, because you have to update all
> test
> >> > > clients also. That's why I prefer @Inject.
> >> > >
> >> > > It would be nice to have some api to override, decorate, and advise
> >> some
> >> > > services on existing (built) registry instance right in the test
> >> method.
> >> > > Maybe (temporarily) replace some service with a mock. So that I
> won't
> >> > have
> >> > > to build new module just to override one service for one test case,
> >> > because
> >> > > it requires additional setup. Just a thoughts.
> >> > >
> >> > >
> >> > > On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
> >> > > <dr...@gmail.com>wrote:
> >> > >
> >> > > > I agree with Dimitry but thats more for integration like testing.
> >> > > > For basic unit testing of services methods (usually we unit test a
> >> > single
> >> > > > method per test) we mock the dependencies (the injected services)
> >> and
> >> > > pass
> >> > > > the mocks through the constructor of the service implementation
> >> class
> >> > > under
> >> > > > test. That's why we prefer constructor based injection.
> >> > > >
> >> > > > If we need to mock methods in the service that's being bested than
> >> we
> >> > > > usually use Spy in Spock or the equivalent feature in other mock
> >> > > > frameworks.
> >> > > >
> >> > > > Cheers,
> >> > > > Dragan Sahpaski
> >> > > >
> >> > > >
> >> > > > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <
> >> dmitry.gusev@gmail.com
> >> > > > >wrote:
> >> > > >
> >> > > > > I usually create base class where I construct registry instance,
> >> > then I
> >> > > > use
> >> > > > > registry.getService(Intf.class) when I need an instance of a
> >> service.
> >> > > > >
> >> > > > > Like here:
> >> > > > >
> >> > > > >
> >> > > >
> >> > >
> >> >
> >>
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> >> > > > >
> >> > > > >
> >> > > > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> >> > > > > <gc...@cardaddy.com>wrote:
> >> > > > >
> >> > > > > > Hello, we are trying to unit test our services, but our
> services
> >> > > > contain
> >> > > > > > other injected services. I'm wondering how you test injected
> >> > > services.
> >> > > > Is
> >> > > > > > there a configuration I'm missing?
> >> > > > > >
> >> > > > > > --
> >> > > > > > George Christman
> >> > > > > > www.CarDaddy.com
> >> > > > > > P.O. Box 735
> >> > > > > > Johnstown, New York
> >> > > > > >
> >> > > > >
> >> > > > >
> >> > > > >
> >> > > > > --
> >> > > > > Dmitry Gusev
> >> > > > >
> >> > > > > AnjLab Team
> >> > > > > http://anjlab.com
> >> > > > >
> >> > > >
> >> > >
> >> > >
> >> > >
> >> > > --
> >> > > Dmitry Gusev
> >> > >
> >> > > AnjLab Team
> >> > > http://anjlab.com
> >> > >
> >> >
> >> >
> >> >
> >> > --
> >> > George Christman
> >> > www.CarDaddy.com
> >> > P.O. Box 735
> >> > Johnstown, New York
> >> >
> >>
> >
> >
> >
> > --
> > George Christman
> > www.CarDaddy.com
> > P.O. Box 735
> > Johnstown, New York
> >
> >
>
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>



-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Re: How do you unit test services with dependent services

Posted by George Christman <gc...@cardaddy.com>.
Am I going about this all the wrong way? Am I using the services correctly?
I never see in any example test code where you guys are having to add all
the modules. Any suggestions?


On Tue, Jan 21, 2014 at 2:47 PM, George Christman
<gc...@cardaddy.com>wrote:

> and that is the easiest way to do it ugh lol
>
>
> On Tue, Jan 21, 2014 at 2:30 PM, Dragan Sahpaski <
> dragan.sahpaski@gmail.com> wrote:
>
>> You have to manually add ALL the tapestry IOC modules you're using (in
>> this
>> case the tapestry-security module
>> org.tynamo.security.services.SecurityModule), because you're starting only
>> the Registry and not the entire webapp.
>>
>> Cheers,
>> Dragan Sahpaski
>>
>>
>> On Tue, Jan 21, 2014 at 8:22 PM, George Christman
>> <gc...@cardaddy.com>wrote:
>>
>> > Dmitry, I'm very confused. I use constructor injection in my services
>> which
>> > I always thought was the correct way to do it based on the tap docs.
>> >
>> > I have the following test class where I'm trying to use a service.
>> >
>> > public class TimeSheetServiceTest {
>> >
>> >     protected static TimeSheetService timeSheetService;
>> >
>> >     @BeforeClass
>> >     public static void setup() {
>> >         Registry registry;
>> >         RegistryBuilder builder = new RegistryBuilder();
>> >         builder.add(AppModule.class);
>> >         registry = builder.build();
>> >         registry.performRegistryStartup();
>> >         timeSheetService = registry.getService(TimeSheetService.class);
>> >     }
>> >
>> >     @Test
>> >     public void testService() {
>> >         int result =
>> >
>> timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
>> >         System.out.println("result " + result);
>> >     }
>> >
>> > }
>> >
>> > TimeSheetService injects another service called UserInfoService userInfo
>> > like so,
>> >
>> > public class TimeSheetServiceImpl implements TimeSheetService {
>> >
>> >     public TimeSheetServiceImpl(UserInfoService userInfo) {
>> >         this.userInfo = userInfo;
>> >     }
>> >
>> > }
>> >
>> > When I try running my test class, I get the following exception.
>> >
>> > <?xml version="1.0" encoding="UTF-8"?>
>> >
>> > <!-- Generated by org.testng.reporters.JUnitReportReporter -->
>> > -<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58 GMT"
>> > failures="1" tests="1"
>> > name="org.domain.etss.services.form.TimeSheetServiceTest"
>> > hostname="hri185169">
>> > <!-- org.domain.etss.services.form.TimeSheetServiceTest -->
>> > -<testcase time="0.000" name="testService"
>> > classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
>> > message="Contribution
>> >
>> >
>> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
>> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
>> > 'SecurityConfiguration', which does not exist."
>> > type="java.lang.IllegalArgumentException">
>> > <![CDATA[java.lang.IllegalArgumentException: Contribution
>> >
>> >
>> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
>> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
>> > 'SecurityConfiguration', which does not exist. at
>> >
>> >
>> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
>> > at
>> >
>> >
>> org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
>> > at
>> org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
>> > at
>> >
>> >
>> org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
>> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
>> >
>> >
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>> > at
>> >
>> >
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>> > at java.lang.reflect.Method.invoke(Method.java:601) at
>> >
>> >
>> org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
>> > at
>> org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
>> > at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213) at
>> > org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) at
>> >
>> >
>> org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
>> > at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
>> at
>> > org.testng.TestRunner.privateRun(TestRunner.java:768) at
>> > org.testng.TestRunner.run(TestRunner.java:617) at
>> > org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
>> > org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
>> > org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
>> > org.testng.SuiteRunner.run(SuiteRunner.java:240) at
>> > org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
>> > org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
>> > org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
>> > org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
>> > org.testng.TestNG.run(TestNG.java:1025) at
>> >
>> org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
>> > at
>> >
>> >
>> org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
>> > at
>> >
>> >
>> org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
>> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
>> >
>> >
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>> > at
>> >
>> >
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>> > at java.lang.reflect.Method.invoke(Method.java:601) at
>> >
>> >
>> org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
>> > at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
>> >
>> >
>> org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
>> > at
>> >
>> >
>> org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
>> > at
>> org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
>> > ]]>
>> > </failure></testcase>
>> > <!-- testService -->
>> > </testsuite>
>> >
>> > From this line
>> >
>> > public static void
>> > contributeSecurityConfiguration(Configuration<SecurityFilterChain>
>> > configuration,
>> >
>> > SecurityFilterChainFactory factory) {
>> >
>> >
>> configuration.add(factory.createChain("/employee/**").add(factory.roles(),
>> > "employee").build());
>> >         configuration.add(factory.createChain("/").add(factory.roles(),
>> > "user").build());
>> >     }
>> >
>> > What am I missing?
>> >
>> >
>> > On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <dmitry.gusev@gmail.com
>> > >wrote:
>> >
>> > > Right, this is for integration testing. I use mocking too, but rarely
>> --
>> > my
>> > > tests are 80% integration ones and involve DB (the same as in
>> > production).
>> > > For mocks I have to use constructor injection also, and this is the
>> only
>> > > reason why I use constructor injections.
>> > > The code looks ugly in this cases, though, when you have more than 5
>> > > dependencies per service. And it's also a tedious task when you want
>> to
>> > add
>> > > another dependency to the service, because you have to update all test
>> > > clients also. That's why I prefer @Inject.
>> > >
>> > > It would be nice to have some api to override, decorate, and advise
>> some
>> > > services on existing (built) registry instance right in the test
>> method.
>> > > Maybe (temporarily) replace some service with a mock. So that I won't
>> > have
>> > > to build new module just to override one service for one test case,
>> > because
>> > > it requires additional setup. Just a thoughts.
>> > >
>> > >
>> > > On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
>> > > <dr...@gmail.com>wrote:
>> > >
>> > > > I agree with Dimitry but thats more for integration like testing.
>> > > > For basic unit testing of services methods (usually we unit test a
>> > single
>> > > > method per test) we mock the dependencies (the injected services)
>> and
>> > > pass
>> > > > the mocks through the constructor of the service implementation
>> class
>> > > under
>> > > > test. That's why we prefer constructor based injection.
>> > > >
>> > > > If we need to mock methods in the service that's being bested than
>> we
>> > > > usually use Spy in Spock or the equivalent feature in other mock
>> > > > frameworks.
>> > > >
>> > > > Cheers,
>> > > > Dragan Sahpaski
>> > > >
>> > > >
>> > > > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <
>> dmitry.gusev@gmail.com
>> > > > >wrote:
>> > > >
>> > > > > I usually create base class where I construct registry instance,
>> > then I
>> > > > use
>> > > > > registry.getService(Intf.class) when I need an instance of a
>> service.
>> > > > >
>> > > > > Like here:
>> > > > >
>> > > > >
>> > > >
>> > >
>> >
>> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
>> > > > >
>> > > > >
>> > > > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
>> > > > > <gc...@cardaddy.com>wrote:
>> > > > >
>> > > > > > Hello, we are trying to unit test our services, but our services
>> > > > contain
>> > > > > > other injected services. I'm wondering how you test injected
>> > > services.
>> > > > Is
>> > > > > > there a configuration I'm missing?
>> > > > > >
>> > > > > > --
>> > > > > > George Christman
>> > > > > > www.CarDaddy.com
>> > > > > > P.O. Box 735
>> > > > > > Johnstown, New York
>> > > > > >
>> > > > >
>> > > > >
>> > > > >
>> > > > > --
>> > > > > Dmitry Gusev
>> > > > >
>> > > > > AnjLab Team
>> > > > > http://anjlab.com
>> > > > >
>> > > >
>> > >
>> > >
>> > >
>> > > --
>> > > Dmitry Gusev
>> > >
>> > > AnjLab Team
>> > > http://anjlab.com
>> > >
>> >
>> >
>> >
>> > --
>> > George Christman
>> > www.CarDaddy.com
>> > P.O. Box 735
>> > Johnstown, New York
>> >
>>
>
>
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>
>


-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: How do you unit test services with dependent services

Posted by George Christman <gc...@cardaddy.com>.
and that is the easiest way to do it ugh lol


On Tue, Jan 21, 2014 at 2:30 PM, Dragan Sahpaski
<dr...@gmail.com>wrote:

> You have to manually add ALL the tapestry IOC modules you're using (in this
> case the tapestry-security module
> org.tynamo.security.services.SecurityModule), because you're starting only
> the Registry and not the entire webapp.
>
> Cheers,
> Dragan Sahpaski
>
>
> On Tue, Jan 21, 2014 at 8:22 PM, George Christman
> <gc...@cardaddy.com>wrote:
>
> > Dmitry, I'm very confused. I use constructor injection in my services
> which
> > I always thought was the correct way to do it based on the tap docs.
> >
> > I have the following test class where I'm trying to use a service.
> >
> > public class TimeSheetServiceTest {
> >
> >     protected static TimeSheetService timeSheetService;
> >
> >     @BeforeClass
> >     public static void setup() {
> >         Registry registry;
> >         RegistryBuilder builder = new RegistryBuilder();
> >         builder.add(AppModule.class);
> >         registry = builder.build();
> >         registry.performRegistryStartup();
> >         timeSheetService = registry.getService(TimeSheetService.class);
> >     }
> >
> >     @Test
> >     public void testService() {
> >         int result =
> >
> timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
> >         System.out.println("result " + result);
> >     }
> >
> > }
> >
> > TimeSheetService injects another service called UserInfoService userInfo
> > like so,
> >
> > public class TimeSheetServiceImpl implements TimeSheetService {
> >
> >     public TimeSheetServiceImpl(UserInfoService userInfo) {
> >         this.userInfo = userInfo;
> >     }
> >
> > }
> >
> > When I try running my test class, I get the following exception.
> >
> > <?xml version="1.0" encoding="UTF-8"?>
> >
> > <!-- Generated by org.testng.reporters.JUnitReportReporter -->
> > -<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58 GMT"
> > failures="1" tests="1"
> > name="org.domain.etss.services.form.TimeSheetServiceTest"
> > hostname="hri185169">
> > <!-- org.domain.etss.services.form.TimeSheetServiceTest -->
> > -<testcase time="0.000" name="testService"
> > classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
> > message="Contribution
> >
> >
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> > 'SecurityConfiguration', which does not exist."
> > type="java.lang.IllegalArgumentException">
> > <![CDATA[java.lang.IllegalArgumentException: Contribution
> >
> >
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> > SecurityFilterChainFactory) (at AppModule.java:312) is for service
> > 'SecurityConfiguration', which does not exist. at
> >
> >
> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
> > at
> >
> >
> org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
> > at
> org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
> > at
> >
> >
> org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> >
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> > at
> >
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > at java.lang.reflect.Method.invoke(Method.java:601) at
> >
> >
> org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
> > at
> org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
> > at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213) at
> > org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) at
> >
> >
> org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
> > at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107) at
> > org.testng.TestRunner.privateRun(TestRunner.java:768) at
> > org.testng.TestRunner.run(TestRunner.java:617) at
> > org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
> > org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
> > org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
> > org.testng.SuiteRunner.run(SuiteRunner.java:240) at
> > org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
> > org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
> > org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
> > org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
> > org.testng.TestNG.run(TestNG.java:1025) at
> >
> org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
> > at
> >
> >
> org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
> > at
> >
> >
> org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
> >
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> > at
> >
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > at java.lang.reflect.Method.invoke(Method.java:601) at
> >
> >
> org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
> > at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
> >
> >
> org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
> > at
> >
> >
> org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
> > at
> org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
> > ]]>
> > </failure></testcase>
> > <!-- testService -->
> > </testsuite>
> >
> > From this line
> >
> > public static void
> > contributeSecurityConfiguration(Configuration<SecurityFilterChain>
> > configuration,
> >
> > SecurityFilterChainFactory factory) {
> >
> >
> configuration.add(factory.createChain("/employee/**").add(factory.roles(),
> > "employee").build());
> >         configuration.add(factory.createChain("/").add(factory.roles(),
> > "user").build());
> >     }
> >
> > What am I missing?
> >
> >
> > On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> > >wrote:
> >
> > > Right, this is for integration testing. I use mocking too, but rarely
> --
> > my
> > > tests are 80% integration ones and involve DB (the same as in
> > production).
> > > For mocks I have to use constructor injection also, and this is the
> only
> > > reason why I use constructor injections.
> > > The code looks ugly in this cases, though, when you have more than 5
> > > dependencies per service. And it's also a tedious task when you want to
> > add
> > > another dependency to the service, because you have to update all test
> > > clients also. That's why I prefer @Inject.
> > >
> > > It would be nice to have some api to override, decorate, and advise
> some
> > > services on existing (built) registry instance right in the test
> method.
> > > Maybe (temporarily) replace some service with a mock. So that I won't
> > have
> > > to build new module just to override one service for one test case,
> > because
> > > it requires additional setup. Just a thoughts.
> > >
> > >
> > > On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
> > > <dr...@gmail.com>wrote:
> > >
> > > > I agree with Dimitry but thats more for integration like testing.
> > > > For basic unit testing of services methods (usually we unit test a
> > single
> > > > method per test) we mock the dependencies (the injected services) and
> > > pass
> > > > the mocks through the constructor of the service implementation class
> > > under
> > > > test. That's why we prefer constructor based injection.
> > > >
> > > > If we need to mock methods in the service that's being bested than we
> > > > usually use Spy in Spock or the equivalent feature in other mock
> > > > frameworks.
> > > >
> > > > Cheers,
> > > > Dragan Sahpaski
> > > >
> > > >
> > > > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <
> dmitry.gusev@gmail.com
> > > > >wrote:
> > > >
> > > > > I usually create base class where I construct registry instance,
> > then I
> > > > use
> > > > > registry.getService(Intf.class) when I need an instance of a
> service.
> > > > >
> > > > > Like here:
> > > > >
> > > > >
> > > >
> > >
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> > > > >
> > > > >
> > > > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > > > > <gc...@cardaddy.com>wrote:
> > > > >
> > > > > > Hello, we are trying to unit test our services, but our services
> > > > contain
> > > > > > other injected services. I'm wondering how you test injected
> > > services.
> > > > Is
> > > > > > there a configuration I'm missing?
> > > > > >
> > > > > > --
> > > > > > George Christman
> > > > > > www.CarDaddy.com
> > > > > > P.O. Box 735
> > > > > > Johnstown, New York
> > > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > Dmitry Gusev
> > > > >
> > > > > AnjLab Team
> > > > > http://anjlab.com
> > > > >
> > > >
> > >
> > >
> > >
> > > --
> > > Dmitry Gusev
> > >
> > > AnjLab Team
> > > http://anjlab.com
> > >
> >
> >
> >
> > --
> > George Christman
> > www.CarDaddy.com
> > P.O. Box 735
> > Johnstown, New York
> >
>



-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: How do you unit test services with dependent services

Posted by Dragan Sahpaski <dr...@gmail.com>.
You have to manually add ALL the tapestry IOC modules you're using (in this
case the tapestry-security module
org.tynamo.security.services.SecurityModule), because you're starting only
the Registry and not the entire webapp.

Cheers,
Dragan Sahpaski


On Tue, Jan 21, 2014 at 8:22 PM, George Christman
<gc...@cardaddy.com>wrote:

> Dmitry, I'm very confused. I use constructor injection in my services which
> I always thought was the correct way to do it based on the tap docs.
>
> I have the following test class where I'm trying to use a service.
>
> public class TimeSheetServiceTest {
>
>     protected static TimeSheetService timeSheetService;
>
>     @BeforeClass
>     public static void setup() {
>         Registry registry;
>         RegistryBuilder builder = new RegistryBuilder();
>         builder.add(AppModule.class);
>         registry = builder.build();
>         registry.performRegistryStartup();
>         timeSheetService = registry.getService(TimeSheetService.class);
>     }
>
>     @Test
>     public void testService() {
>         int result =
> timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
>         System.out.println("result " + result);
>     }
>
> }
>
> TimeSheetService injects another service called UserInfoService userInfo
> like so,
>
> public class TimeSheetServiceImpl implements TimeSheetService {
>
>     public TimeSheetServiceImpl(UserInfoService userInfo) {
>         this.userInfo = userInfo;
>     }
>
> }
>
> When I try running my test class, I get the following exception.
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <!-- Generated by org.testng.reporters.JUnitReportReporter -->
> -<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58 GMT"
> failures="1" tests="1"
> name="org.domain.etss.services.form.TimeSheetServiceTest"
> hostname="hri185169">
> <!-- org.domain.etss.services.form.TimeSheetServiceTest -->
> -<testcase time="0.000" name="testService"
> classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
> message="Contribution
>
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> SecurityFilterChainFactory) (at AppModule.java:312) is for service
> 'SecurityConfiguration', which does not exist."
> type="java.lang.IllegalArgumentException">
> <![CDATA[java.lang.IllegalArgumentException: Contribution
>
> org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
> SecurityFilterChainFactory) (at AppModule.java:312) is for service
> 'SecurityConfiguration', which does not exist. at
>
> org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
> at
>
> org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
> at org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
> at
>
> org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> at
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:601) at
>
> org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
> at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
> at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213) at
> org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) at
>
> org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
> at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107) at
> org.testng.TestRunner.privateRun(TestRunner.java:768) at
> org.testng.TestRunner.run(TestRunner.java:617) at
> org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
> org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
> org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
> org.testng.SuiteRunner.run(SuiteRunner.java:240) at
> org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
> org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
> org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
> org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
> org.testng.TestNG.run(TestNG.java:1025) at
> org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
> at
>
> org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
> at
>
> org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> at
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:601) at
>
> org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
> at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
>
> org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
> at
>
> org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
> at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
> ]]>
> </failure></testcase>
> <!-- testService -->
> </testsuite>
>
> From this line
>
> public static void
> contributeSecurityConfiguration(Configuration<SecurityFilterChain>
> configuration,
>
> SecurityFilterChainFactory factory) {
>
> configuration.add(factory.createChain("/employee/**").add(factory.roles(),
> "employee").build());
>         configuration.add(factory.createChain("/").add(factory.roles(),
> "user").build());
>     }
>
> What am I missing?
>
>
> On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> >wrote:
>
> > Right, this is for integration testing. I use mocking too, but rarely --
> my
> > tests are 80% integration ones and involve DB (the same as in
> production).
> > For mocks I have to use constructor injection also, and this is the only
> > reason why I use constructor injections.
> > The code looks ugly in this cases, though, when you have more than 5
> > dependencies per service. And it's also a tedious task when you want to
> add
> > another dependency to the service, because you have to update all test
> > clients also. That's why I prefer @Inject.
> >
> > It would be nice to have some api to override, decorate, and advise some
> > services on existing (built) registry instance right in the test method.
> > Maybe (temporarily) replace some service with a mock. So that I won't
> have
> > to build new module just to override one service for one test case,
> because
> > it requires additional setup. Just a thoughts.
> >
> >
> > On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
> > <dr...@gmail.com>wrote:
> >
> > > I agree with Dimitry but thats more for integration like testing.
> > > For basic unit testing of services methods (usually we unit test a
> single
> > > method per test) we mock the dependencies (the injected services) and
> > pass
> > > the mocks through the constructor of the service implementation class
> > under
> > > test. That's why we prefer constructor based injection.
> > >
> > > If we need to mock methods in the service that's being bested than we
> > > usually use Spy in Spock or the equivalent feature in other mock
> > > frameworks.
> > >
> > > Cheers,
> > > Dragan Sahpaski
> > >
> > >
> > > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> > > >wrote:
> > >
> > > > I usually create base class where I construct registry instance,
> then I
> > > use
> > > > registry.getService(Intf.class) when I need an instance of a service.
> > > >
> > > > Like here:
> > > >
> > > >
> > >
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> > > >
> > > >
> > > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > > > <gc...@cardaddy.com>wrote:
> > > >
> > > > > Hello, we are trying to unit test our services, but our services
> > > contain
> > > > > other injected services. I'm wondering how you test injected
> > services.
> > > Is
> > > > > there a configuration I'm missing?
> > > > >
> > > > > --
> > > > > George Christman
> > > > > www.CarDaddy.com
> > > > > P.O. Box 735
> > > > > Johnstown, New York
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > Dmitry Gusev
> > > >
> > > > AnjLab Team
> > > > http://anjlab.com
> > > >
> > >
> >
> >
> >
> > --
> > Dmitry Gusev
> >
> > AnjLab Team
> > http://anjlab.com
> >
>
>
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>

Re: How do you unit test services with dependent services

Posted by George Christman <gc...@cardaddy.com>.
Dmitry, I'm very confused. I use constructor injection in my services which
I always thought was the correct way to do it based on the tap docs.

I have the following test class where I'm trying to use a service.

public class TimeSheetServiceTest {

    protected static TimeSheetService timeSheetService;

    @BeforeClass
    public static void setup() {
        Registry registry;
        RegistryBuilder builder = new RegistryBuilder();
        builder.add(AppModule.class);
        registry = builder.build();
        registry.performRegistryStartup();
        timeSheetService = registry.getService(TimeSheetService.class);
    }

    @Test
    public void testService() {
        int result =
timeSheetService.getHolidayListForPayPeriod(Calendar.getInstance()).size();
        System.out.println("result " + result);
    }

}

TimeSheetService injects another service called UserInfoService userInfo
like so,

public class TimeSheetServiceImpl implements TimeSheetService {

    public TimeSheetServiceImpl(UserInfoService userInfo) {
        this.userInfo = userInfo;
    }

}

When I try running my test class, I get the following exception.

<?xml version="1.0" encoding="UTF-8"?>

<!-- Generated by org.testng.reporters.JUnitReportReporter -->
-<testsuite errors="0" time="0.000" timestamp="21 Jan 2014 19:18:58 GMT"
failures="1" tests="1"
name="org.domain.etss.services.form.TimeSheetServiceTest"
hostname="hri185169">
<!-- org.domain.etss.services.form.TimeSheetServiceTest -->
-<testcase time="0.000" name="testService"
classname="org.domain.etss.services.form.TimeSheetServiceTest">-<failure
message="Contribution
org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
SecurityFilterChainFactory) (at AppModule.java:312) is for service
'SecurityConfiguration', which does not exist."
type="java.lang.IllegalArgumentException">
<![CDATA[java.lang.IllegalArgumentException: Contribution
org.domain.etss.services.AppModule.contributeSecurityConfiguration(Configuration,
SecurityFilterChainFactory) (at AppModule.java:312) is for service
'SecurityConfiguration', which does not exist. at
org.apache.tapestry5.ioc.internal.RegistryImpl.validateContributeDefs(RegistryImpl.java:236)
at
org.apache.tapestry5.ioc.internal.RegistryImpl.<init>(RegistryImpl.java:200)
at org.apache.tapestry5.ioc.RegistryBuilder.build(RegistryBuilder.java:170)
at
org.domain.etss.services.form.TimeSheetServiceTest.setup(TimeSheetServiceTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:551)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213) at
org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138) at
org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107) at
org.testng.TestRunner.privateRun(TestRunner.java:768) at
org.testng.TestRunner.run(TestRunner.java:617) at
org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329) at
org.testng.SuiteRunner.privateRun(SuiteRunner.java:291) at
org.testng.SuiteRunner.run(SuiteRunner.java:240) at
org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at
org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:87) at
org.testng.TestNG.runSuitesSequentially(TestNG.java:1188) at
org.testng.TestNG.runSuitesLocally(TestNG.java:1113) at
org.testng.TestNG.run(TestNG.java:1025) at
org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:72)
at
org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:88)
at
org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
at com.sun.proxy.$Proxy0.invoke(Unknown Source) at
org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
at
org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
]]>
</failure></testcase>
<!-- testService -->
</testsuite>

>From this line

public static void
contributeSecurityConfiguration(Configuration<SecurityFilterChain>
configuration,

SecurityFilterChainFactory factory) {

configuration.add(factory.createChain("/employee/**").add(factory.roles(),
"employee").build());
        configuration.add(factory.createChain("/").add(factory.roles(),
"user").build());
    }

What am I missing?


On Tue, Jan 21, 2014 at 1:00 PM, Dmitry Gusev <dm...@gmail.com>wrote:

> Right, this is for integration testing. I use mocking too, but rarely -- my
> tests are 80% integration ones and involve DB (the same as in production).
> For mocks I have to use constructor injection also, and this is the only
> reason why I use constructor injections.
> The code looks ugly in this cases, though, when you have more than 5
> dependencies per service. And it's also a tedious task when you want to add
> another dependency to the service, because you have to update all test
> clients also. That's why I prefer @Inject.
>
> It would be nice to have some api to override, decorate, and advise some
> services on existing (built) registry instance right in the test method.
> Maybe (temporarily) replace some service with a mock. So that I won't have
> to build new module just to override one service for one test case, because
> it requires additional setup. Just a thoughts.
>
>
> On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
> <dr...@gmail.com>wrote:
>
> > I agree with Dimitry but thats more for integration like testing.
> > For basic unit testing of services methods (usually we unit test a single
> > method per test) we mock the dependencies (the injected services) and
> pass
> > the mocks through the constructor of the service implementation class
> under
> > test. That's why we prefer constructor based injection.
> >
> > If we need to mock methods in the service that's being bested than we
> > usually use Spy in Spock or the equivalent feature in other mock
> > frameworks.
> >
> > Cheers,
> > Dragan Sahpaski
> >
> >
> > On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> > >wrote:
> >
> > > I usually create base class where I construct registry instance, then I
> > use
> > > registry.getService(Intf.class) when I need an instance of a service.
> > >
> > > Like here:
> > >
> > >
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> > >
> > >
> > > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > > <gc...@cardaddy.com>wrote:
> > >
> > > > Hello, we are trying to unit test our services, but our services
> > contain
> > > > other injected services. I'm wondering how you test injected
> services.
> > Is
> > > > there a configuration I'm missing?
> > > >
> > > > --
> > > > George Christman
> > > > www.CarDaddy.com
> > > > P.O. Box 735
> > > > Johnstown, New York
> > > >
> > >
> > >
> > >
> > > --
> > > Dmitry Gusev
> > >
> > > AnjLab Team
> > > http://anjlab.com
> > >
> >
>
>
>
> --
> Dmitry Gusev
>
> AnjLab Team
> http://anjlab.com
>



-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: How do you unit test services with dependent services

Posted by Dmitry Gusev <dm...@gmail.com>.
Right, this is for integration testing. I use mocking too, but rarely -- my
tests are 80% integration ones and involve DB (the same as in production).
For mocks I have to use constructor injection also, and this is the only
reason why I use constructor injections.
The code looks ugly in this cases, though, when you have more than 5
dependencies per service. And it's also a tedious task when you want to add
another dependency to the service, because you have to update all test
clients also. That's why I prefer @Inject.

It would be nice to have some api to override, decorate, and advise some
services on existing (built) registry instance right in the test method.
Maybe (temporarily) replace some service with a mock. So that I won't have
to build new module just to override one service for one test case, because
it requires additional setup. Just a thoughts.


On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
<dr...@gmail.com>wrote:

> I agree with Dimitry but thats more for integration like testing.
> For basic unit testing of services methods (usually we unit test a single
> method per test) we mock the dependencies (the injected services) and pass
> the mocks through the constructor of the service implementation class under
> test. That's why we prefer constructor based injection.
>
> If we need to mock methods in the service that's being bested than we
> usually use Spy in Spock or the equivalent feature in other mock
> frameworks.
>
> Cheers,
> Dragan Sahpaski
>
>
> On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> >wrote:
>
> > I usually create base class where I construct registry instance, then I
> use
> > registry.getService(Intf.class) when I need an instance of a service.
> >
> > Like here:
> >
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> >
> >
> > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > <gc...@cardaddy.com>wrote:
> >
> > > Hello, we are trying to unit test our services, but our services
> contain
> > > other injected services. I'm wondering how you test injected services.
> Is
> > > there a configuration I'm missing?
> > >
> > > --
> > > George Christman
> > > www.CarDaddy.com
> > > P.O. Box 735
> > > Johnstown, New York
> > >
> >
> >
> >
> > --
> > Dmitry Gusev
> >
> > AnjLab Team
> > http://anjlab.com
> >
>



-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Re: How do you unit test services with dependent services

Posted by Dmitry Gusev <dm...@gmail.com>.
Here's one recent thread that on the same subject:
http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Testing-Tapestry-td5723590.html


On Tue, Jan 21, 2014 at 9:41 PM, Dragan Sahpaski
<dr...@gmail.com>wrote:

> I agree with Dimitry but thats more for integration like testing.
> For basic unit testing of services methods (usually we unit test a single
> method per test) we mock the dependencies (the injected services) and pass
> the mocks through the constructor of the service implementation class under
> test. That's why we prefer constructor based injection.
>
> If we need to mock methods in the service that's being bested than we
> usually use Spy in Spock or the equivalent feature in other mock
> frameworks.
>
> Cheers,
> Dragan Sahpaski
>
>
> On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <dmitry.gusev@gmail.com
> >wrote:
>
> > I usually create base class where I construct registry instance, then I
> use
> > registry.getService(Intf.class) when I need an instance of a service.
> >
> > Like here:
> >
> >
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
> >
> >
> > On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> > <gc...@cardaddy.com>wrote:
> >
> > > Hello, we are trying to unit test our services, but our services
> contain
> > > other injected services. I'm wondering how you test injected services.
> Is
> > > there a configuration I'm missing?
> > >
> > > --
> > > George Christman
> > > www.CarDaddy.com
> > > P.O. Box 735
> > > Johnstown, New York
> > >
> >
> >
> >
> > --
> > Dmitry Gusev
> >
> > AnjLab Team
> > http://anjlab.com
> >
>



-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Re: How do you unit test services with dependent services

Posted by Dragan Sahpaski <dr...@gmail.com>.
I agree with Dimitry but thats more for integration like testing.
For basic unit testing of services methods (usually we unit test a single
method per test) we mock the dependencies (the injected services) and pass
the mocks through the constructor of the service implementation class under
test. That's why we prefer constructor based injection.

If we need to mock methods in the service that's being bested than we
usually use Spy in Spock or the equivalent feature in other mock frameworks.

Cheers,
Dragan Sahpaski


On Tue, Jan 21, 2014 at 6:34 PM, Dmitry Gusev <dm...@gmail.com>wrote:

> I usually create base class where I construct registry instance, then I use
> registry.getService(Intf.class) when I need an instance of a service.
>
> Like here:
>
> https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java
>
>
> On Tue, Jan 21, 2014 at 9:07 PM, George Christman
> <gc...@cardaddy.com>wrote:
>
> > Hello, we are trying to unit test our services, but our services contain
> > other injected services. I'm wondering how you test injected services. Is
> > there a configuration I'm missing?
> >
> > --
> > George Christman
> > www.CarDaddy.com
> > P.O. Box 735
> > Johnstown, New York
> >
>
>
>
> --
> Dmitry Gusev
>
> AnjLab Team
> http://anjlab.com
>

Re: How do you unit test services with dependent services

Posted by Dmitry Gusev <dm...@gmail.com>.
I usually create base class where I construct registry instance, then I use
registry.getService(Intf.class) when I need an instance of a service.

Like here:
https://github.com/anjlab/anjlab-tapestry-commons/blob/master/anjlab-tapestry-quartz/src/test/java/com/anjlab/tapestry5/services/quartz/SchedulerTest.java


On Tue, Jan 21, 2014 at 9:07 PM, George Christman
<gc...@cardaddy.com>wrote:

> Hello, we are trying to unit test our services, but our services contain
> other injected services. I'm wondering how you test injected services. Is
> there a configuration I'm missing?
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>



-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com