How to fake InitialContext with default constructor

powermockito mock constructor
powermock expect
easymock mock constructor
powermockito whennew multiple constructors
expectnew mockito

All,

I'm trying to do some unit testing in some archaic java code (no interfaces, no abstraction, etc.)

This is a servlet that uses a ServletContext (which I'm assuming is set up by Tomcat) and it has database information is set up in the web.xml/context.xml file. Now, I've figured out how to make a Fake ServletContext, but the code has

 InitialContext _ic = new InitialContext();

all over the place (so it isn't feasible to replace it). I need to find a way to make a default InitialContext() able to do the _ic.lookup(val) without throwing an exception.

I'm assuming there is some way that the context.xml is getting loaded, but how that magic works, I'm drawing a blank. Anyone have any ideas?

You can use PowerMock to mock construction of the InitialContext and control its behavior. Constructor Mocking is documented here.

PowerMock tests can be quite messy and complicated, refactoring is normally a better option.

How to mock InitialContext constructor in unit testing, //Mock context and JNDI InitialContext cntxMock = PowerMock. How to fake InitialContext with default constructor, PowerMock tests can be quite messy and  Hi-I'm running WLS 5.1 on NT 4.0 (SP6).For some reason, I'm unable to use the default constructor to get an initial context. That is, if I try: InitialContext ctx = new InitialContext(); I get a NoInitialContextException, as in: "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" This does

Take advantage of the fact that InitialContext uses an SPI to handle its creation. You can hook into its lifecycle by creating an implementation of javax.naming.spi.InitialContextFactory and passing that to your tests via the system property javax.naming.factory.initial (Context.INTITIAL_CONTEXT_FACTORY). It's simpler than it sounds.

Given this class:

public class UseInitialContext {

    public UseInitialContext() {
        try {
            InitialContext ic = new InitialContext();
            Object myObject = ic.lookup("myObject");
            System.out.println(myObject);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }


} 

And this impl of InitialContextFactory:

public class MyInitialContextFactory implements InitialContextFactory {

    public Context getInitialContext(Hashtable<?, ?> arg0)
            throws NamingException {

        Context context = Mockito.mock(Context.class);
        Mockito.when(context.lookup("myObject")).thenReturn("This is my object!!");
        return context;
    }
}

Creating an instance of UseInitialContext in a junit test with

-Djava.naming.initial.factory=initial.context.test.MyInitialContext

on the command line outputs This is my object!! (easy to set up in eclipse). I like Mockito for mocking and stubbing. I'd also recommend Micheal Feather's Working Effectively with Legacy Code if you deal with lots of legacy code. It's all about how to find seams in programs in order to isolate specific pieces for testing.

javax.naming.InitialContext.createSubcontext java code examples , How to fake InitialContext with default constructor. public static void setupInitialContext() throws Exception { System.setProperty(Context. When the environment property "java.naming.factory.initial" is non-null, the InitialContext constructor will attempt to create the initial context specified therein. At that time, the initial context factory involved might throw an exception if a problem is encountered.

Here's my solution to setting up the Inintial Context for my unit tests. First I added the following test dependency to my project:

<dependency>
  <groupId>org.apache.tomcat</groupId>
  <artifactId>catalina</artifactId>
  <version>6.0.33</version>
  <scope>test</scope>
</dependency>

Then I created a static method with the following code:

public static void setupInitialContext() throws Exception {
    System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
    System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
    InitialContext ic = new InitialContext();
    ic.createSubcontext("jdbc");
    PGSimpleDataSource ds = new PGSimpleDataSource();
    ds.setDatabaseName("postgres");
    ds.setUser("postgres");
    ds.setPassword("admin");
    ic.bind("jdbc/something", ds);
}

Finally in each of my test class I add an @BeforeClass method which calls setupInitialContext.

javax.naming.InitialContext.bind java code examples, How to fake InitialContext with default constructor. public static void setupInitialContext() throws Exception { System.setProperty(Context. Hiro2k. I like Java and Python. 74. answers. 8. questions ~977k. 6 How to fake InitialContext with default constructor Apr 6 '12. 6 4 hours in currentTimeMillis

Try setting up the system variables before:

System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
        "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES,
        "org.apache.naming");
InitialContext ic = new InitialContext();

If you are using JUnit, follow this doc: https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit

Using PowerMock to Mock Constructors, In my opinion, one of the main benefits of dependency injection is that you can inject mock and/or stub objects into your code in order to  Default constructors are called during default initializations and value initializations. [ edit ] Implicitly-declared default constructor If no user-declared constructors of any kind are provided for a class type ( struct , class , or union ), the compiler will always declare a default constructor as an inline public member of its class.

Today I've faced the same problem (we can't user PowerMock) and solved it this way:

  1. Don't lookup in the constructor so when you invoke @InitMock on the object, the constructor doesn't require the context yet.

  2. Create a method for retrieving the service bean when needed like "getService().serviceMethod(param, param ...)":

    /* Class ApplicationResourceProvider */

    /* We can mock this and set it up with InjectMocks */
    InitialContext ic;

    /* method hiding the lookup */
    protected ApplicationService getService() throws NamingException {
        if(ic == null)
            ic = new InitialContext();
        return (ApplicationService)ic.lookup("java:global/defaultApplicationLocal");
    }
  1. On the test, set it up:
@Mock
ApplicationService applicationServiceBean;

@Mock
InitialContext ic;

@InjectMocks
ApplicationResourceProvider arp;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    when(ic.lookup(anyString())).thenReturn(applicationServiceBean);
    ...
}

net.sourceforge.sqlunit.test.mock Class MockInitialContext, Overrides the InitialContext to provide an in-memory lookup mechanism instead of network lookup. Default constructor used by the MockInitialContextFactory. To create a WebLogic context from a client, your code must minimally specify this factory as the initial context factory, and the URL of a WebLogic Server in the JNDI environment, as properties passed to the constructor of InitialContext. Here's an example of the minimal setup required to establish a context:

InitialContext (Java Platform SE 8 ), This default policy of locating the initial context and URL context factories may be the InitialContext constructor will attempt to create the initial context specified  Creating the Initial Context You are now ready to create the initial context. To do that, you pass to the InitialContext constructor the environment properties that you created previously: Context ctx = new InitialContext(env); Now that you have a reference to a Context object, you can begin to access the naming service.

Testing - Project Metadata API Guide, The mock JNDI support in the org.springframework.mock.jndi package on a test class, the default test constructor autowire mode will be used. I tried different solutions (like putting the "new StreamReader("filename")" call into a method and replacing the whole method with "new StreamReader(new MemoryStream(Encoding.Default.GetBytes("33\r 1\r 16\r 5\r 7")))", but it would be more elegant todo this via Constructor Mocking / Replacing because then i do not have to alter existing code.

Don't mock infrastructure, I have been down the path of mocking JNDI, JDBC, JMS, that accepts an Context and a default constructor that creates an InitialContext. This might be a stupid question but I can't find a lot of information on the web about creating your own default constructors in C++. It seems to just be a constructor with no parameters.

Comments
  • Just because it occurs a lot doesn't mean it's definitely infeasible to replace it. Heck, even just changing to use a static factory method would allow more testability (although it's clearly not as nice as some alternatives).
  • +1. PowerMock is powerful but it's definitely caused enough headaches that refactoring is much preferred.
  • I think this is the best solution for what i'm trying to do. thanks!
  • Avoid PowerMock unless you have no other option left open to you... Plenty of articles explaining why.
  • Instead of 'java.naming.initial.factory', I think the correct system property is 'java.naming.factory.initial'. At least in java 6. Thanks for the post!
  • 'java.naming.factory.initial' is also for java 7.
  • FWIW, i wrote a very similar answer to a very similar question some time after this, and i did this using a JUnit TestTule to handle the setup and teardown.
  • Context.INITIAL_CONTEXT_FACTORY so you don't want to remember the actual string value for the initial context factory environment variable name.
  • in relation to this blogs.oracle.com/randystuph/entry/… was very good
  • This gives java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory
  • you are supposed to have the tomcat environment in your project. You have to add the tomcat jars
  • So if I am using JBoss I guess I have to use JBoss environment. Thank you!
  • The link to oracle blog is broken