PowerMock - NPE on #PrepareForTest - java

Problem: The instrumentation class in PowerMock isn't being initialized. I'm loading the library through the #Rule annotation. I've got the VM argument in place:
-javaagent:project_path/libs/powermock-module-javaagent-1.5.jar
When I walk through with the debugger, PowerMockAgent#premain gets called and the instrumentation object gets set, but when it's called during the test setup, the instrumentation object is null, throwing the error below.
Why is the instrumentation variable not keeping it's value between when PowerMockAgent#premain is called and when PowerMockClassRedefiner.redefine calls it?
Instrumentation gets set correctly here on load:
private static void initialize(String agentArgs, Instrumentation inst) throws IOException {
instrumentation = inst;
inst.addTransformer(new DefinalizingClassTransformer(), false);
inst.addTransformer(classTransformer, true);
}
But when called again from #PrepareForTest({ Logger.class }), is null
public class PowerMockClassRedefiner {
public static void redefine(Class<?> cls) {
if(cls == null) {
throw new IllegalArgumentException("Class to redefine cannot be null");
}
PowerMockAgent.getClasstransformer().setClassesToTransform(Arrays.asList(cls.getName()));
try {
PowerMockAgent.instrumentation().retransformClasses(cls);
} catch(Exception e){
throw new RuntimeException("Failed to redefine class "+cls.getName(), e);
}
}
Resulting in error:
java.lang.RuntimeException: Failed to redefine class com.testapp.Logger
at org.powermock.modules.agent.PowerMockClassRedefiner.redefine(PowerMockClassRedefiner.java:33)
at org.powermock.modules.agent.PowerMockClassRedefiner.redefine(PowerMockClassRedefiner.java:42)
at com.testapp.testFramework.PowerMockRuleAgentSetup.redefine(PowerMockRuleAgentSetup.java:29)
at com.testapp.testFramework.PowerMockRuleAgentSetup.initialize(PowerMockRuleAgentSetup.java:19)
at com.testapp.testFramework.PowerMockOverriderRule.apply(PowerMockOverriderRule.java:19)
at org.junit.runners.BlockJUnit4ClassRunner.withMethodRules(BlockJUnit4ClassRunner.java:341)
at org.junit.runners.BlockJUnit4ClassRunner.withRules(BlockJUnit4ClassRunner.java:330)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:248)
at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:287)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
at org.powermock.modules.agent.PowerMockClassRedefiner.redefine(PowerMockClassRedefiner.java:31)
... 22 more
Here's my test setup:
#RunWith(RobolectricTestRunner.class)
#PrepareForTest({ Logger.class }) // THIS IS WHERE THE ERROR GETS THROWN
public class LoggerTest {
#Rule public PowerMockOverriderRule rule = new PowerMockOverriderRule();
public LoggerConfig config;
#Before
public void setUp() {
config = mock(LoggerConfig.class);
}
UPDATE:
Removing the #RunWith(RobolectricTestRunner.class) fixes the problem, but isn't an option for my project. (It's an Android project).

I'm sorry to ask but why would you even want to mock a Logger class? If you want to ensure that the output is logged to the console you can wrap a logger in an abstraction that you can mock.
class LogWraper {
void someMethod() {
logger.log()
}
}
and then you can create a mock of your FooWraper. No need to use Powermock at all...

Related

Testing Interface methods using Mockito

I am writing a JUnit test case for a method which internally invokes another method through interface. I am using Mockito to mock the interface but for some reason it gives me NPE. I debugged through but wasn't able to get any clue to fix it. getAllVendors() method throws exception which comes through an Interface.
MUT
public void prepare() throws AccountServiceException, ManagerException {
vendors = getVendorManager().getAllVendors();
microsites = new ArrayList<VendorMicrositeTO>();
microsites.add( new VendorMicrositeTO( "http://www.docusign.com", "docuSign" ) );
clientUser = createClientUserObject();
}
JUnit
#Test
public void testPrepare() throws Exception {
AccountAction accountAction = new AccountAction();
Map<String, Object> actionMap = new HashMap<>();
actionMap.put("application", "ESignatureIntegrationAction");
ActionContext.setContext(new ActionContext(actionMap));
String beanName = Constants.VENDOR_MANAGER_SPRING_BEAN;
PowerMockito.mockStatic(AppContext.class);
PowerMockito.when(AppContext.containsBean( beanName )).thenReturn( true );
IVendorDto iVendorDto = new VendorDto();
iVendorDto.setActive(true);
iVendorDto.setCreatedBy("9/15/2016");
iVendorDto.setName("CorpESignClientUser");
iVendorDto.setCreatedBy("SYSTEM");
List<IVendorDto> vendorList = new ArrayList<>();
vendorList.add(iVendorDto);
IVendorManager iManager = Mockito.mock((IVendorManager.class));
Mockito.when(iManager.getAllVendors()).thenReturn(vendorList);
accountAction.setVendors(vendorList);
accountAction.prepare();
}
Stack trace
java.lang.NullPointerException
at com.mercuryinsurance.esignature.ui.webapp.action.AccountAction.prepare(AccountAction.java:65)
at test.com.mercuryinsurance.esignature.ui.webapp.action.TestAccountAction.testPrepare(TestAccountAction.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Thanks, in advance
Seems you forgot to add a line in your test like:
accountAction.setVendorManager(iManager);
So yeah, I have been tackling a very similar issue.
This usecase is a logical outcome of the application of the SOLID principles within an IoT based application. If you decouple the layers of your application using interfaces and are testing an innner layer you are bound to come across testing an interface whose implementations have more interface dependencies.
You can achieve this goal using two testing angles combined
Use the Parameterized JUnit runner to launch the one set of unit tests for all of the implementations.
Then internally during each run initialize the mocked dependencies using Mockito
For more information on Parameterized testing (that's where i originally found it) be sure to visit this post. The manual initialization of mockito was something i found here.
All and all the resulting code looks like this:
#RunWith(Parameterized.class)
public class YourInterfaceTest {
#Mock
private ImplementationDependency sneakyBreakyNpeAvoided;
#InjectMocks
private YourInterfaceToTest iface;
// constructor is used by the Parameterized runner to provide impelementations
public YourInterfaceTest (YourInterfaceToTest ifaceToTest) {
this.iface = ifaceToTest;
}
// this method is called always before running tests so a good time to inject anything
#Before
public void init() {
MockitoAnnotations.initMocks(this);
Mockito.when(sneakyBreakyNpeAvoided.returnTrue()).thenReturn(true);
}
#Test(expected = IllegalArgumentException.class)
public void doSomething_nullParameter_throwsIllegalArgumentException() {
Assert.fail(); // tests here :)
}
#Parameterized.Parameters
public static Collection<YourInterfaceToTest > provideImplementations() {
// change to Arrays.asList when multiple implementations are available
return Collections.singletonList(new YourInterfaceImpl());
}
}
Hope I understood the OP's issue well.

Test Eclipse 4 RCP Application. Provide necessary Objects

I´m developing an Eclipse 4 RCP Application and I want to test some functions of my Parts.
I have a Test Class like this:
#BeforeClass
public static void initUI() {
display = new Display();
shell = new Shell(display);
configPart = new ConfigPart();
configPart.postConstruct(shell);
}
#Test
public void testConfigPart() {
String testText = "TitleText";
configPart.title.setText(testText);
assertEquals(testText, ConfigHandler.getInstance().getInternalConfig()
.getTitle());
}
During the creation of the ConfigPart a DataBinding is created and that is where I run into an AssertionFailedException. The statement is:
DataBindingContext ctx = new DataBindingContext();
Is there a way to avoid this or is there another way to test E4 Applications?
Edit:
The statement(s) where the Exception is raised:
public DataBindingContext(Realm validationRealm) {
Assert.isNotNull(validationRealm, "Validation realm cannot be null");
public static void isNotNull(Object object, String message) {
if (object == null) throw new AssertionFailedException("null argument:" + message);
The Stack Trace:
org.eclipse.core.runtime.AssertionFailedException: null argument:Validation realm cannot be null
at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
at org.eclipse.core.databinding.DataBindingContext.<init>(DataBindingContext.java:95)
at org.eclipse.core.databinding.DataBindingContext.<init>(DataBindingContext.java:82)
at de.uni_due.s3.jack.editor.parts.config.ConfigPart.addDataBinding(ConfigPart.java:350)
at de.uni_due.s3.jack.editor.parts.config.ConfigPart.postConstruct(ConfigPart.java:81)
at de.uni_due.s3.jack.editor.parts.config.ConfigPartTest.initUI(ConfigPartTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
A call to the empty constructor new DataBindingContext() delegates to this(Realm.getDefault()) (see Eclipse source code). This means that you need to have some kind of a stub Realm set as default for your testing purposes.
You can use this solution from the Eclipse Wiki. Here is a copy-paste from the Wiki (adapted for your setup). I would think about whether you really need to have the setup in #BeforeClass or if #Before would be better.
public class DefaultRealm extends Realm {
private Realm previousRealm;
public DefaultRealm() {
previousRealm = super.setDefault(this);
}
/**
* #return always returns true
*/
public boolean isCurrent() {
return true;
}
protected void syncExec(Runnable runnable) {
runnable.run();
}
/**
* #throws UnsupportedOperationException
*/
public void asyncExec(Runnable runnable) {
throw new UnsupportedOperationException("asyncExec is unsupported");
}
/**
* Removes the realm from being the current and sets the previous realm to the default.
*/
public void dispose() {
if (getDefault() == this) {
setDefault(previousRealm);
}
}
}
Test code:
private static DefaultRealm realm;
#BeforeClass
public static void initUI() {
display = new Display();
shell = new Shell(display);
realm = new DefaultRealm();
configPart = new ConfigPart();
configPart.postConstruct(shell);
}
#AfterClass
public static void tearDownUI() {
realm.dispose();
}

How could I test ClassNotFoundException is being thrown?

I have question that similar to my previous question where I have the following class:
public class FileClass {
public void funcB() throws ClassNotFoundException {
throw new ClassNotFoundException();
}
}
I would like to test whether ClassNotFoundException will be thrown when funcB() is called. Thus I have this test code:
public class TestFileClass {
#Test(expected=ClassNotFoundException.class)
public void testFuncB() throws ClassNotFoundException {
FileClass fc = Mockito.spy(new FileClass());
Mockito.doThrow(new ClassNotFoundException())
.when(fc).funcB();
}
}
But the test were failed due to following error:
java.lang.AssertionError: Expected exception: java.lang.ClassNotFoundException
at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:35)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Any clue how could I test ClassNotFoundException in funcB()?
If you're testing a method invocation on an instance of type FileClass, don't mock the instance. Just create an actual instance and call the method.
#Test(expected = ClassNotFoundException.class)
public void testFuncB() throws ClassNotFoundException {
FileClass fc = new FileClass();
fc.funcB();
}
Mocking is meant for things that you know ([would]) work but don't want to setup.
As #dzezzz states in the comments, a ClassNotFoundException (is that really the exception you want to test?) could be thrown in the FileClass constructor. If that is not something that should happen and that you want to test, you can set up the following test so that it is only expected from the method invocation
#Rule
public ExpectedException exception = ExpectedException.none();
#Test()
public void testFuncB() throws ClassNotFoundException {
FileClass fc = new FileClass();
exception.expect(ClassNotFoundException.class);
fc.funcB();
}
The test will pass only if a ClassNotFoundException is thrown after the ExpectedException#expect() call.
If you test FileClass then don't mock it. You should mock the classes which are used by FileClass.
If you don't want that the exception will come out from test method.
There is a solution:
#Test(expected = ClassNotFoundException.class)
public void testFuncB(){
try{
FileClass fc = new FileClass();
fc.funcB();
fail();
}catch(ClassNotFoundException ex){
}
}
In this solution you catch the exception if it is thrown but your test fails when it isn't.

PowerMock - Mocking static system class throws IllegalStateException

I have the following code
public class A{
public void createFile() {
File tempXmlFile = null;
String extension = ".xml";
String name = "someName";
try {
tempXmlFile = File.createTempFile(name, extension);
if (tempXmlFile.exists()) {
tempXmlFile.delete();
}
} catch (IOException e) {
System.out.println(e.getStackTrace());
}
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(A.class)
public class testA extends TestCase{
private A classUnderTest;
#Override
#Before
public void setUp() {
classUnderTest = PowerMock.createMock(A.class); //the class is more complex in my case and I have to mock it
}
public void testCreateFile() throws IOException{
String extension = ".xml";
String name = "someName";
PowerMock.mockStatic(File.class);
File tempFileMock = PowerMock.createMock(File.class);
expect(File.createTempFile(name, extension)).andReturn(tempFileMock);
expect(tempFileMock.exists()).andReturn(true);
expect(tempFileMock.delete()).andReturn(true);
replay(File.class, tempFileMock, classUnderTest);
classUnderTest.createFile();
verify(File.class, tempFileMock, classUnderTest);
}
}
In the test class as I said the class under test must be mocked(I can't create a new object).
When I run the test I get:
java.lang.IllegalStateException: no last call on a mock available
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:174)
at org.easymock.EasyMock.expect(EasyMock.java:156)
at myPackage.testA.testCreateFile(testA.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:163)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:113)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:111)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:87)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:44)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I read the documentation here http://code.google.com/p/powermock/wiki/MockSystem but the test stil wont't work. Am I missing something?
Edit: I tested the previous code with a real A object (and removed it from replay)
classUnderTest = new A();
but I still get the same exception.
Try adding File.class to #PrepareForTest.
try the org.powermock.reflect.internal.WhiteboxImpl.newInstance() method to create the object of the class and then call method directly.
1) this will suppress the constructor of the class
2) if your class contains static block then use suppressStaticInitilaizationFor to suppress that.
regards
Anil Sharma
Add File.class to #PrepareForTest and check the imports of replay and verify. They should be from PowerMock.
I think you need to suppress constructor
Check this
http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior

No tx on thread CMP OpenEJB4 JUnit Hibernate

I keep getting the following exception,
java.lang.IllegalStateException: No tx on thread at org.apache.geronimo.transaction.manager.TransactionManagerImpl.getActiveTransactionImpl(TransactionManagerImpl.java:201)
at org.apache.geronimo.transaction.manager.TransactionManagerImpl.getResource(TransactionManagerImpl.java:194)
at org.apache.openejb.core.transaction.JtaTransactionPolicy.getResource(JtaTransactionPolicy.java:111)
at org.apache.openejb.core.transaction.EjbTransactionUtil.afterInvoke(EjbTransactionUtil.java:76)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:246)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:178)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:260)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:240)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:91)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:284)
at $Proxy70.call(Unknown Source)
at com.xyz.cms.epgmgmt.entitymanager.ProviderManagerTest.testWithTransaction(ProviderManagerTest.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:243)
at junit.framework.TestSuite.run(TestSuite.java:238)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I am using OpenEJB4 for JUnit testing.
The EJB itself is stateless with no transaction annotation (which makes the Transaction required). I found an older post on this forum and tried the same fix but didnt work. I dont have hibernate validation on my classpath. Am using Hibernate 3.
My test is as follows,
public class ProviderManagerTest extends TestCase {
Context context;
/**
* Bootstrap the Embedded EJB Container
*
* #throws Exception
*/
protected void setUp() throws Exception {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory");
p.put("log4j.category.OpenEJB.options ", " debug");
p.put("RcsDB", "new://Resource?type=DataSource");
p.put("RcsDB.JdbcDriver", "oracle.jdbc.driver.OracleDriver");
p.put("RcsDB.JdbcUrl", "jdbc:oracle:thin:#dbserver:1521:ttv");
p.put("RcsDB.JtaManaged", "true");
p.put("RcsDB.JtaManaged", "true");
p.put("RcsDB.username", "username");
p.put("RcsDB.password", "password");
context = EJBContainer.createEJBContainer(p).getContext();
context.bind("inject", this);
}
#Test
public void testWithTransaction() throws Exception {
Caller transactionalCaller = (Caller) context.lookup("java:global/cms_epgmgmt/TransactionBean");
transactionalCaller.call(new Callable() {
public Object call() throws Exception {
Provider testProvider = new Provider();
testProvider.setName("test");
IProviderManager providerManager = null;
providerManager = (IProviderManager) context.lookup("java:global/cms_epgmgmt/ProviderManager");
providerManager.create(testProvider);
return null;
}
});
}
/*private void testProviderCreation()
{
Provider testProvider = new Provider();
testProvider.setName("test");
providerManager.create(testProvider);
}
*/
public static interface Caller {
public <V> V call(Callable<V> callable) throws Exception;
}
/**
* This little bit of magic allows our test code to execute in
* the scope of a container controlled transaction.
*/
#Stateless
#TransactionAttribute(REQUIRES_NEW)
public static class TransactionBean implements Caller {
public <V> V call(Callable<V> callable) throws Exception {
return callable.call();
}
}
}
where provider manager is as below,
#Local(IProviderManager.class)
#Stateless
public class ProviderManager implements IProviderManager{
#PersistenceContext(unitName = "epgmanagerjpaunit")
private EntityManager entityManager;
public void create(Provider provider)
{
entityManager.persist(provider);
}
}
Thanks in advance,
-v-

Categories

Resources