Unit testing: Correct way to instantiate UiUtils in a context sensitive test?

Hi all,

What is the recommended way to instantiate UiUtils in a context sensitive unit test? I found this (in an old school unit test):

UiUtils ui = new BasicUiUtils();

Which is fine, except that for instance ui.contextPath() returns null. Everything else looks null on that beast anyway:

Try add this line in your TestingApplicationContext.xml: https://github.com/openmrs/openmrs-module-uiframework/blob/master/omod/src/main/resources/webModuleApplicationContext.xml#L90

Thanks for the prompt response @dkayiwa.

So I added a api/src/test/resources/TestingApplicationContext.xml file like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <bean id="uiUtils" class="org.openmrs.ui.framework.BasicUiUtils" init-method="init"/>

</beans>

I autowired UiUtils in my test class:

@Autowired
@Qualifier("uiUtils")
private UiUtils ui;

… and I’m getting this:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'conversionService' is defined

That looks like caused by something else. How does your test look like?

I committed everything in a tmp branch, you can clone it here: https://github.com/mekomsolutions/openmrs-module-visitdocumentsui/tree/tmp The test in question is here.

Add this line to your TestingApplicatioContext.xml https://github.com/openmrs/openmrs-module-uiframework/blob/master/api/src/test/resources/TestingApplicationContext.xml#L24

Yes, this worked, thanks!

It works, I can see that UiUtils is now filled up. However calling ui.contextPath() still returns a null string. Is there a way to set this up somewhere, again this is for the sake of a unit test.

If you would like it to have a certain value, then just assign it to WebConstants.CONTEXT_PATH

Mmm, I just did this in my unit test setup:

context.getAdministrationService().saveGlobalProperty( new GlobalProperty(WebConstants.CONTEXT_PATH, "openmrs" ) );
String contextPath = ui.contextPath();

And contextPath is still null…

I mean this: org.openmrs.ui.framework.WebConstants = “openmrs”;

Right… Ok this works.

Strange that context sensitive tests don’t fill this variable with “openmrs” by default.

That is expected because this value is filled in the activator of the uiframework module. In this case, there is no activator being called and hence what you are seeing. https://github.com/openmrs/openmrs-module-uiframework/blob/master/api/src/main/java/org/openmrs/module/uiframework/UiFrameworkActivator.java#L74

@dkayiwa / @mksd, perhaps the right solution for these unit tests is to put something like this in an @Before method, rather than try to recreate the logic:

UiFrameworkActivator activator = new UiFrameworkActivator();
activator.contextRefreshed();  

Thoughts? Mike

@mksd do you wanna try that out?

Thanks @mseaton for throwing yet another idea. In the context of my tests I needed really little out of UiUtils, there would only be calls to

  1. UiUtils#contextPath()
  2. UiUtils#toJson(Object)

The former can be dealth with a mock, but I needed an actual instance of UiUtils for the latter.

I guess your suggestion implies that, after those instructions, I will be in a position to call new BasicUiUtils(), correct? And the context path will set as well as anything else.

I haven’t fully followed this thread, but the other way to do what I think you’re doing is:

new BasicUiUtils() {
    @Override
    public String getContextPath() { ... }
}

That’s quite a nifty one, it could totally work in my current use case. We tend to forget about inline overrides as we are stuck in DI and forbidden to use new!