Unit testing Java actions

7
Are there any best practices to adhear to when unit testing your Java actions? I'm finding it difficult to call a Java action from within a unit test when I have to specifcy parameters of type module.proxies.MendixObject. I can't initalize one of these objects without an IContext or IMendixObject.
asked
3 answers
7

It is possible to test your full action including the Mendix specific stuff. You will have to create a generic setUp and tearDown method in your unit tests, starting the Mendix XAS from code. You also need to login using Java API calls to obtain a session / context.

The listing below shows a code example starting an XAS and logging in with the MxAdmin user. Check that the path to your model file in the ConsoleMenu.main() line is correct. For unit testing purposes it is the best to split the code below in a setUp and tearDown method. The Session object only needs to be created once. The context object needs to be created before each action call.

import java.util.List;
import com.mendix.core.Core;
import com.mendix.core.session.Session;
import com.mendix.externalinterface.menu.ConsoleMenu;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.systemwideinterfaces.core.ISession;


public class XASStarter
{

    public static void main(String[] args) throws Exception
    {
        //Start the Mendix XAS in a separate Thread
        XASStarterThread starter = new XASStarterThread();
        starter.start();

        //Wait for the XAS to be fully started
        Thread.sleep(10000);

        //Create a session and authenticate that session
        ISession session = new Session();
        Core.login(session, "MxAdmin", "1", "EN_en");

        //Create a new context for executing actions on the XAS
        IContext ctx = session.getContext();

        //Example action
        List<IMendixObject> result = Core.retrieveXPathQuery(ctx, "//System.User");
        System.out.println(result.size());

        //Stop the XAS
        Core.shutdownNow();
    }

    static class XASStarterThread extends Thread
    {
        @Override
        public void run()
        {
            ConsoleMenu.main(new String[]{"-f", "WEB-INF/model/dataView.mdp", "-m", "DEV"});            
        }
    }

}
answered
6

You could remove the mx.jar from your classpath and build your own interfaces to adhere to. That way, you can run the unit tests with "mock" contexts and mendixobjects.

However, that seems kinda overkill for what you're trying to do. Is the functionality really that tightly coupled to MendixObjects? It seems like it would be easier to make separate methods that aren't coupled to Mendix at all, that way you can JUnit test them separately without the need for MendixObjects or IContexts.

In other words, instead of:

public boolean viewMendixObject(IMendixObject myobject) {
 // do stuff
}

you could try:

public boolean viewMendixObject(Map<String, String> mendixObjectMembers) {
 // do stuff that doesn't require mx.jar 
}
answered
0

I faced similar issue, for getting Context object while authoring JUnit tests. I resolved it using below code.

@Test
....
IContext context = Core.createSystemContext();
....

 

answered