I am trying to mock a final class
PowerMockito.mockStatic(TestFinalClass.class);
It is working from my eclipse when I run a single junit and add javaagent to my VM arguments
-javaagent:{path}/powermock-module-javaagent-1.6.4.jar
But when I try to run all test cases from command line using maven build command I am still getting "Cannot subclass final class"
Below is my snippet from pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4</version>
<configuration>
<argLine>-javaagent:{path}/powermock-module-javaagent-1.6.4.jar</argLine>
</configuration>
</plugin>
package test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(FinalClass.class)
public class Tests {
#Test
public void test() {
PowerMockito.mockStatic(FinalClass.class);
}
}
This works for me. If you add 'PowerMockRunner' and 'PrepareForTest' annotations you don`t need to use extra vm arguments.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(FinalClass.class)
public class TestFinalClass{
#Test
public void whenMockFinalClassMockWorks() {
FinalClass finalklass = PowerMockito.mock(FinalClass.class);
}
}
I got the code coverage using JaCoCo and need to make some changes related to it in the test class code. Those are as below:
I removed #RunWith annotation
Added #Rule and PowerMockRule class
Mentioned the Final and Static class in #PrepareForTest
#PrepareForTest(FinalClass.class, StaticClass.class)
public class Tests {
#Rule
public PowerMockRule rule = new PowerMockRule();
#Test
public void test() {
PowerMockito.mockStatic(FinalClass.class);
PowerMockito.mockStatic(StaticClass.class);
}
}
Also added the argline in surefire to overcome the final class problem while mocking.
<configuration>
<argLine>-javaagent:{path}/powermock-module-javaagent-1.6.4.jar</argLine>
</configuration>
Related
I'm building an automation framework using Cucumber for BDD, JUnit and Selenium, we have a testrail instance in the cloud for test management and I implemented the testrail API for getting all the test cases from there, the problem is I'm not able to run these steps for getting the test cases because cucumber always validate first feature file exist.
I've tried with #Before (Cucumber), #BeforeClass (JUnit) and the result is always the same:
No features found at [classpath:features]
0 Scenarios
0 Steps
0m0.019s
This is the main class starting the process:
import cucumber.api.CucumberOptions;
import cucumber.api.java.Before;
import cucumber.api.junit.Cucumber;
import org.apache.log4j.Logger;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import static
com.mps.framework.support.support.Property.BROWSER_NAME;
#RunWith(Cucumber.class)
#CucumberOptions(
plugin = "json:target/cucumber.json",
features = {"classpath:features"},
glue = {"com.selenium.test.stepdefinitions", "com.mps.selenium.hook"},
tags = {"not #ignore"})
public class SeleniumCukes {
private static final Logger LOG = Logger.getLogger(SeleniumCukes.class);
#BeforeClass
public static void startSelenium() {
LOG.info("### Starting Selenium " +
BROWSER_NAME.toString().toUpperCase() + " ###");
}
#AfterClass
public static void stopSelenium() {
LOG.info("### Stopping Selenium ###");
}
}
This is the hooks class:
import com.mps.selenium.base.SeleniumBase;
import cucumber.api.Scenario;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import org.springframework.beans.factory.annotation.Autowired;
import static com.mps.framework.support.hook.Hooks.hookAfter;
import static com.mps.framework.support.hook.Hooks.hookBefore;
public class Hooks {
#Autowired
private SeleniumBase seleniumBase;
#After
public void after() {
hookAfter(seleniumBase.getDriver());
}
#Before
public void before(Scenario scenario) {
hookBefore(scenario);
}
}
I'm not sure what you are trying to achieve but it think what you are looking for is the annotation #BeforeSuite (use the import annotations.BeforeSuite)
Here I have wrote a simple test case using Junit and Mockito.
import org.jbehave.core.annotations.Given;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
import com.test.dao.login.LoginDao;
import com.test.mapping.user.User;
import com.test.service.login.LoginService;
import com.test.service.login.impl.LoginServiceImpl;
import com.test.util.common.Common;
public class UserLoginSteps {
#Mock
Common common;
#Mock
LoginDao loginDao;
#InjectMocks
LoginService loginService =new LoginServiceImpl();
#BeforeClass
public static void beforeClass() {
System.out.println("#BeforeClass");
}
#Before
public void before() {
System.out.println("#Before");
MockitoAnnotations.initMocks(this);
}
#After
public void after() {
System.out.println("#After");
}
#AfterClass
public static void afterClass() {
System.out.println("#AfterClass");
}
#Given("$username username and $password password")
#Test
public void checkUser(String username, String password) throws Exception{
when(common.checkNullAndEmpty("admin")).thenReturn(true);
when(common.checkNullAndEmpty("password")).thenReturn(true);
when(loginDao.getUser("admin","password")).thenReturn(new User());
assertEquals(true,loginService.checkValidUser(username, password));
}
}
I have initialize the Mock objects inside the before() function.
But that function is not triggered out in running the test case.
I am using following dependencies.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.8.9</version>
<scope>test</scope>
</dependency>
I have seen similar questions to this scenario.
But the following suggestions does not fix the issue.
Is any one can describe why it happen and how to fix this issue it will be great helpful.
Thanks in advance.
After-before-not-working-in-testcase
Simple-junit-class-is-not-calling-the-before-method
Why-isnt-my-beforeclass-method-running
You should annotate your class with #RunWith(MockitoJUnitRunner.class) So the MickitoJunitRunner will take care of your Mocks and tests. But it will not work like this together with JBehave. You have to decide if you want to use JBehave or MockitoJUnitRunner.
In JBehave the correct annotations to use are: #BeforeScenario #AfterScenario #BeforeStory #AfterStory Please take a look at jbehave doc: http://jbehave.org/reference/stable/annotations.html
Is it a bug of Powermock or I'm doing sth wrong?
The following test should pass, but failed with:
trackBugPartialMockCountMore(com.xiaomi.finddevice.test.testcase.PowerMockBug)
org.mockito.exceptions.verification.TooManyActualInvocations:
classToMock.foo();
Wanted 1 time:
-> at com.xiaomi.finddevice.test.testcase.PowerMockBug.trackBugPartialMockCountMore(PowerMockBug.java:24)
But was 3 times. Undesired invocation:
-> at com.xiaomi.finddevice.test.testcase.PowerMockBug.trackBugPartialMockCountMore(PowerMockBug.java:22)
When I remove #PrepareForTest(ClassToMock.class), every thing goes well and the test get passed.
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassToMock.class)
public class PowerMockBug {
#Test
public void trackBugPartialMockCountMore() {
ClassToMock mock = mock(ClassToMock.class);
when(mock.foo()).thenCallRealMethod();
mock.foo();
verify(mock).foo();
}
}
class ClassToMock {
public int foo() { return 0x10; }
}
VERSION: powermock-mockito-junit-1.6.3
In your example you don't need to use PowerMock because you are not mocking/spying a final or static method. You can safely remove both #RunWith and #PrepareForTest annotations. Only mockito is needed for your purposes
I am trying to write Unit test cases using power mockito.
When using annotations #RunWith(PowerMockRunner.class) I am getting the following compilation error:-
TypeMismatch: cannot convert from Class<PowerMockRunner> to Class<? extends Runner>
Here is the code snippet. Using junit 4.8.1 and power mock 1.6.2.
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
public class XXXTest {
#Test
public void testOne() {
if (true)
System.out.println("Success");
}
}
I downloaded and added Powermock-Module-Junit4 jar and did not add the dependent jar Powermock-Module-Junit4-Common.jar. When added common jar Powermock-Module-Junit4-Common resolved the error.
Thanks,
Vasu.
I have some simple classes I'm using to see if I can get powermock to work:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(Foo.class)
public class FooTest
{
#Test
public void testFoobar(){
Foo test = PowerMock.createPartialMock(Foo.class, "foobar");
PowerMock.replay(test);
}
}
and
public class Foo
{
public String foobar(String aString){
return aString + " blah";
}
}
When I try to run this unit test, it tells me:
java.lang.NoClassDefFoundError: org/easymock/classextension/internal/ClassProxyFactory$MockMethodInterceptor
...
I have no idea why its doing this. Please help.
Make sure you're including EasyMock in your class path when using PowerMock... you can find the download page here.
According to the Wiki on PowerMock, it states that EasyMock is a dependency.