Schlagwort-Archive: maven

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.

maven android eclipse

prerequired:

  • Maven3 installed
  • Eclipse 3.7 or greater
  • maven – plugin
  • android plugin

create sturcture with maven.
Terminal:
go to Project Folder.

mvn archetype:generate | grep android
46: remote -&gt; com.googlecode.android-player-root-archetype:parent-archetype (-)
110: remote -&gt; com.vektorsoft.demux.tools:demux-android-archetype (Create Android application structure for DEMUX Framework applications)
117: remote -&gt; de.akquinet.android.archetypes:android-gcm-quickstart (Creates a skeleton for a GCM Android application)
118: remote -&gt; de.akquinet.android.archetypes:android-library-quickstart (Creates a skeleton for an Android library)
119: remote -&gt; de.akquinet.android.archetypes:android-quickstart (Creates a skeleton for an Android application)
120: remote -&gt; de.akquinet.android.archetypes:android-release (Creates a skeleton for an Android application,
121: remote -&gt; de.akquinet.android.archetypes:android-with-test (Creates a skeleton for an Android application and instrumentation tests)
122: remote -&gt; de.akquinet.android.archetypes:stand-archetype (Creates a skeleton for an Android application using the Stand framework stack)
531: remote -&gt; org.eclipse.xtend:xtend-android-archetype (-)
826: remote -&gt; ru.nikitav.android.archetypes:release (-)
827: remote -&gt; ru.nikitav.android.archetypes:release-robolectric (-)
^C

Keep ID 119 in mind and enter it.

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 296: 119

Choose a version (latest recommend)

Choose de.akquinet.android.archetypes:android-quickstart version: 
1: 1.0.0
2: 1.0.1
3: 1.0.2
4: 1.0.3
5: 1.0.4
6: 1.0.5
7: 1.0.6
8: 1.0.7
9: 1.0.8
10: 1.0.9
11: 1.0.10
12: 1.0.11

Define a groupId, artefactId, version, package etc. and confirm with Y:

Define value for property 'groupId': : de.ingoreschke.annuitycalculator
Define value for property 'artifactId': : app-full
Define value for property 'version':  1.0-SNAPSHOT: : 1.0.0
Define value for property 'package':  de.ingoreschke.annuitycalculator: : de.ingoreschke.annuitycalculator.full
Define value for property 'android-plugin-version':  3.6.0: : 
Define value for property 'emulator':  not-specified: : 
Define value for property 'platform':  16: : 17
Confirm properties configuration:
groupId: de.ingoreschke.annuitycalculator
artifactId: app-full
version: 1.0.0
package: de.ingoreschke.annuitycalculator.full
android-plugin-version: 3.6.0
emulator: not-specified
platform: 16

New Module in Main pom.xml

<?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.o
  3   <modelVersion>4.0.0</modelVersion>
  4   <groupId>de.ingoreschke</groupId>
  5   <artifactId>annuitycalculator</artifactId>
  6   <version>0.0.1-SNAPSHOT</version>
  7   <packaging>pom</packaging>
  8   <name>Main Project Folder</name>
  9   <description>This will be hold all sub projects Android, Java, Website to Annuity Calculator Project</description>
 10   <modules>
 11     <module>core</module>
 12     <module>app_full</module>
 13   </modules>
 14 </project>

Pom.xml in new Project app_full

<?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.o
  3     <modelVersion>4.0.0</modelVersion>
  4     <parent>
  5     <artifactId>annuitycalculator</artifactId>
  6     <groupId>de.ingoreschke</groupId>
  7     <version>0.0.1-SNAPSHOT</version>
  8   </parent>
  9     <groupId>de.ingoreschke.annuitycalculator</groupId>
 10     <artifactId>app_full</artifactId>
 11     <version>1.0-SNAPSHOT</version>
 12     <packaging>apk</packaging>
 13     <name>app_full</name>
 14     <properties>
 15         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 16         <platform.version>4.1.1.4</platform.version>
 17         <android.plugin.version>3.6.0</android.plugin.version>
 18     </properties>
 19     <dependencies>
 20         <dependency>
 21             <groupId>com.google.android</groupId>
 22             <artifactId>android</artifactId>
 23             <version>${platform.version}</version>
 24             <scope>provided</scope>
 25         </dependency>
 26     </dependencies>
 27     <build>
 28         <finalName>${project.artifactId}</finalName>
 29         <pluginManagement>
 30             <plugins>
 31                 <plugin>
 32                     <groupId>com.jayway.maven.plugins.android.generation2</groupId>
 33                     <artifactId>android-maven-plugin</artifactId>
 34                     <version>${android.plugin.version}</version>
 35                     <extensions>true</extensions>
 36                 </plugin>
 37             </plugins>
 38         </pluginManagement>
 39         <plugins>
 40             <plugin>
 41                 <groupId>com.jayway.maven.plugins.android.generation2</groupId>
 42                 <artifactId>android-maven-plugin</artifactId>
 43                 <configuration>
 44                     <sdk>
 45                         <platform>16</platform>
 46                     </sdk>
 47                 </configuration>
 48             </plugin>
 49         </plugins>
 50     </build>
 51 </project>
<pre>
 
<pre lang="bash">mvn clean install

In Eclipse
Import the new Maven Modul.
After Import I got a Error:
Project 'app_full' is missing required source folder: 'src/test/java'
Fixed it by adding a folder test/java into src.
Bildschirmfoto 2013-09-11 um 00.28.35

Source: a screencast found on youtube. http://www.youtube.com/watch?v=S7XDsivkVUA