0

I am facing big problem instantiating weblogic Initial context while running jUnit tests. Application uses Spring / hibernate / weblogic. In application code, methods uses JMS proxy to send messages to JMS, Queues are setup on weblogic.

My problem is while JUnit tests currently I need to keep weblogic server running on local machine just to initialize WeblogicInitialContext which is used in JMS proxies. My junit test don't need to send anything to server, NO JMS , NO datasources. All are handeled by spring unit test framework. I want to decouple/ get rid of Weblogic for my junit tests. Please suggest. Here is my code:

This is my test application context XML:

<beans xmlns="http://www.springframework.org/schema/beans"
...
>

<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<util:properties id="webLogicInitialContext">
    <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
    <prop key="java.naming.provider.url">t3://localhost:7001</prop>
    <prop key="java.naming.security.principal">admin</prop>
    <prop key="java.naming.security.credentials">password</prop>
</util:properties>

<jee:jndi-lookup id="responseProxyConnectionFactory"
    jndi-name="jms/ConnectionFactory" environment-ref="webLogicInitialContext"/>

<bean id="responseProxyJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory"
        ref="responseProxyConnectionFactory" />
</bean>
</beans>

This is One Java class methods :

public class Order {
    public void addOrder(OrderRequest addOrderRequest) {
        PurchaseOrder newOrder = orderHelper.createOrder(addOrderRequest);
        orderDaoHibernate.addOrder(newOrder);
        responseProxy.send(newOrder);

    }
}

My Test :

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners( {TransactionalTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,DirtiesContextTestExecutionListener.class })
@ContextConfiguration(locations={"/test-application-context.xml"})
@TransactionConfiguration(defaultRollback=true) 

public class TestOrder {

    @Test
    @Transactional
    public void testMyOrder(){
        Order ord = new Order();
        OrderRequest req = new OrderRequest();
        ....
        ord.addOrder(req);
    }

}

If I run this test the Spring framework try to load the WeblogicInitialContext , and if local weblogic not running it throws exceptions.

I don't want to send any JMS message when I call this method from Junit. How can I create dummy WeblogicInitialContext.

Please help.

Some part of Exception;

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean     with name 'responseProxyConnectionFactory': Invocation of init method failed; nested exception is javax.naming.CommunicationException [Root exception is java.net.ConnectException: t3://localhost:7001: Destination unreachable; nested exception is: 
vinS
  • 1,417
  • 5
  • 24
  • 37
utsuk
  • 1
  • 1
  • 1
  • Some solutions here: [How to mock InitialContext constructor in unit testing](https://stackoverflow.com/q/36734275/772981). – Jarekczek Jun 29 '17 at 07:32

2 Answers2

2

One way to deal with this problem is this:

Split your application configuration in two parts,

  • a core part - where your normal classes are defined, injected, scanned, ...
  • a server dependent part (containing all the stuff which can not been created in the test)

Add a spring config, that import them both, and use this when you start your application.

So for test you can use the core-part-configuration. If this configuration can not be instanciated, because some beans (form the server dependent part) are missing you need to mock them. Here you have two choices:

  • create a test mock configuration, that simulated the server dependent part by mocks.
  • you could try to add the mocks programaticaly to the application context, before you load the core part. (much more compicated)

Anyway: I strongly recommend to rethink the way you build tests. May a better way is to build some (not all) tests completely without spring and create the class under test by hand (new) and "inject" the objects needed for the test by hand. The objects not needed for the test (at all, or because the make the test only more difficult but not better) should be replaced by Mocks.


To create mocked, I prefere the mocking framwork jMock. I have implemented a Helper Class with a Factory method, which create a class, and create and inject Mocks for all fields annoted by @Autorwird/@Ressourse.

Ralph
  • 118,862
  • 56
  • 287
  • 383
  • Tks. That's the problem, how do I create the mock server side part. How can I mock the WeblogicInitialContext in my spring config files? I just don't want to load this context. But Proxies in my code are using it. Control never goes to code level but my tests fails whilie initialising spring config files itself. – utsuk Apr 12 '11 at 16:05
  • @utsuk: I have extended my anwer. Is this what you was asking for? – Ralph Apr 12 '11 at 16:20
  • Tks Ralph. I am not currently using any mock framework but look inti this jMock you mentioned. Actually what I am looking for is a way to mimick WLInitialContextFactory by some means in my spring config file. Like by replacing it with some other kind of context factory , so that I don't need to start weblogic locally. I just want that my tests don't fail while loading spring config files coz it cannot find WLInitialContextFactory. for eg. replace it with some dummy factory say "dummyContectFactory or "SpringInitialContextFactory" . – utsuk Apr 12 '11 at 16:33
  • ..continued.. then my responseProxy code will get this mock factory and configs load fine. eg: dummy.jndi.DummyContextFactory http://localhost:7001 admin password – utsuk Apr 12 '11 at 16:34
  • I expect, you inject only the results of the factory, but not the factory itself. So I think you do not need to "mock" the factory. Just remove the factory, an add the result of the factory to you test context. – Ralph Apr 12 '11 at 16:36
  • @Ralph I think I didn't understand what you meant by "result of the factory" , how shall i remove the factory? I tried this , if that's what you men but still it throws error. – utsuk Apr 12 '11 at 18:24
  • ...continued.. the error is: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial – utsuk Apr 12 '11 at 18:26
  • @utsuk: what I meant was: I expect, that you use the factory for something. Now the idea was not to simulate the factory, but the "something". – Ralph Apr 13 '11 at 05:26
0

If this were a common context that you're sharing with your production application, I would say that can avoid instantiating the database and JMS stuff by moving the JMS related beans into a different context that is loaded only by your main application and not test code.

But since this is a dedicated test context, you can probably simply remove those beans that are not needed, such as the weblogic config and the jndi context lookup bean. If you still need a jms queue to test again, you can use a mock, as described in this SO question.

Community
  • 1
  • 1
mdma
  • 56,943
  • 12
  • 94
  • 128
  • I tried that . If i remove these weblogic config beans, It start throwing other exceptions that InitialContext cannot be found etc.. actulaly mostly all methods in my application send JMS via proxy and in my config xml that reponseProxy uses weblogicContext. In my code i can make change / put a switch that don't send JMS when called by unit test BUT the problem is SPRING loads all config XML's before even going to code. I wan't to avoid that load ofany Initial context , or use some mock InitialContext. – utsuk Apr 12 '11 at 15:51