Be a Mentor, not a Tormentor.

Venkat Subramaniam at DEVOXX 2019

Knowlegde is the a wealth that grows when given

Venkat Subramaniam at DEVOXX 2019

Criticize Ideas, Not People.

Venkat Subramaniam at DEVOXX 2019

Prototyping beats argumenting.

Venkat Subramaniam at DEVOXX 2019

Learn happens in deltas.

Venkat Subramaniam at DEVOXX 2019

A Good Architect Practices what the Preach.

There will be people you love,
Who can’t stay for ever,
And there will be things you can’t fix,
Although you are clever.

unbekannt

Mocking SessionContext

I have a EJB:

@Stateless
@Remote
public class ejbBean implements EjbBean {
	@PersistenceContext
	private EntityManager em;
	@Resource
	private SessionContext ctx;
 
	public String someMethod() {
		String name = ctx.getCallerPrincipal().getName();
		return name;
	}
}
public class EjbBeanTest {
	@Rule
	public final MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
	@Mock
	private EntityManager em;
	@Mock
	private SessionContext ctx;
 
	@InjectMocks
	private EjbBean cut;
 
	@Before
	public void setUp() {
		Principal p = mock(Principal.class);
		when(ctx.getCallerPrincipal()).thenReturn(p);
		when(p.getName()).thenReturn("TestUser");
	}
 
	@Test
	public void test() {
		String result = cut.someMethod();
		assertEquals("TestUser", result);
	}

causes the following exception

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: interface javax.ejb.SessionContext.

Mockito can only mock non-private & non-final classes.

I made lot of searches over the web. (google, stackOverflow, git, everywhere)
I found some suggestions like https://stackoverflow.com/questions/32695925/how-do-i-mock-a-sessioncontext-injected-via-resource-in-java-ee.
I tried everything.
But what ever I tried I got failing test with the Error message above.
WTF.
My friend give me the tip … Don`t use an mocking framework, make your own dummy.
OK lets try this. Fill the one method I need then instantiate this.

public class DummySessionContext implements SessionContext {
...
	@Override
	public Principal getCallerPrincipal() {
		// TODO Auto-generated method stub
		Principal principal = () -> "TESTUSER";
		return principal;
	}
...	
}

And this brings a new Error up.

java.lang.Error: Unresolved compilation problems: 
	The type javax.xml.rpc.handler.MessageContext cannot be resolved. It is indirectly referenced from required .class files
	MessageContext cannot be resolved to a type

It turns out that there was a missing dependency in pom.
Because we have scope = provide

<dependency>
	<groupId>org.jboss.spec.javax.ejb</groupId>
	<artifactId>jboss-ejb-api_3.2_spec</artifactId>
	<scope>provided</scope>
</dependency>

my mentor said

provided -> means provided by ejb container
provided dependencies will NOT be there for tests
I think you have to create dependency with test

I added the following to my pom

<!-- needed SessionContext mock-->
<dependency>
	<groupId>org.jboss.spec.javax.xml.rpc</groupId>
	<artifactId>jboss-jaxrpc-api_1.1_spec</artifactId>
	<version>1.0.1.Final</version>
	<scope>test</scope>
</dependency>

Now the test works fine.
With my own dummy.
EJB:

@Stateless
@Remote
public class ejbBean implements EjbBean {
	@PersistenceContext
	private EntityManager em;
	private SessionContext ctx;
 
	@Resource
	void setSessionContext(SessionContext ctx) {
		this.ctx = ctx;
	}
 
	public String someMethod() {
		String name = ctx.getCallerPrincipal().getName();
		return name;
	}
}

Dummy:

public class DummySessionContext implements SessionContext {
...
	@Override
	public Principal getCallerPrincipal() {
		// TODO Auto-generated method stub
		Principal principal = () -> "TESTUSER";
		return principal;
	}
...	
}

TEST:

public class EjbBeanTest {
	@Rule
	public final MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
	@Mock
	private EntityManager em;
 
 
	@InjectMocks
	private EjbBean cut;
 
	@Before
	public void setUp() {
		cut.setSessionContext(new DummySessionContext());
	}
 
	@Test
	public void test() {
		String result = cut.someMethod();
		assertEquals("TestUser", result);
	}
}

Furthermore I tried to mock again.
And now this works too.

EJB:

@Stateless
@Remote
public class ejbBean implements EjbBean {
	@PersistenceContext
	private EntityManager em;
	@Resource
	private SessionContext ctx;
 
	public String someMethod() {
		String name = ctx.getCallerPrincipal().getName();
		return name;
	}
}

TEST:

public class EjbBeanTest {
	@Rule
	public final MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
	@Mock
	private EntityManager em;
	@Mock
	private SessionContext ctx;
 
	@InjectMocks
	private EjbBean cut;
 
 
	@Test
	public void test() { 
		Principal p = mock(Principal.class);
		when(ctx.getCallerPrincipal()).thenReturn(p);
		when(p.getName()).thenReturn("TestUser");
 
		String result = cut.someMethod();
		assertEquals("TestUser", result);
	}
}

Conclusion
I my case using the mockito hides the missing dependency. And I had a hard time to figure it out.
Many thanks to my friend and Sensai Jiri.

Search Engine shortcuts

Working with shortcuts will increase your speed and make your work more effective.
I discovered a new cool shortcut.
When I search something on the web I’m switching over several search engines. Like Metager, Google, StackOverflow, GitHub, Wikipedia.
You can set a keyword to the engine.

  1. click „Burger menu“ -> „Einstellungen“ -> „Suche“
  2. double click on the Entry and enter keyword.

searchengine

Now you can simply type into the address bar the chosen shortcut followed by what you like to search.
For Example git java lamda
CTRL+L – switch to address bar or CTRL-T – open a new Tab
s lamda for each – perform https://stackoverflow.com/search?q=lamda+foreach