Mocking method inside a static class using powermock - java

I have a static method inside a class as follows:
public class config {
public static boolean isProcess() {
return false;
}
}
I am trying to mock the method isProcess as follows:
#RunWith(PowerMockRunner.class)
#PrepareForTest (config.class)
public class testConfig {
public static void main(String[] args) {
PowerMock.mockStatic(config.class);
expect(config.isProcess()).andReturn(true);
PowerMock.replay(config.class);
PowerMock.verify(config.class);
}
}
When I run the testConfig class, I get the following exception
Exception in thread "main" java.lang.IllegalStateException: no last
call on a mock available at
org.easymock.EasyMock.getControlForLastCall(EasyMock.java:466) at
org.easymock.EasyMock.expect(EasyMock.java:444) at
testConfig.main(testConfig.java:18)
Can some one help with this please?

Related

How to execute a piece of code once before all test classes start?

How can I execute a method once before all tests in all classes start?
I have a program that needs a system property to be set before any test start. Is there any way to do that?
Note: #BeforeClass or #Before are used just for the same test class. In my case, I'm looking for a way to execute a method before all test classes start.
To setup precondition to your test cases you can use something like this -
#Before
public void setUp(){
// Set up you preconditions here
// This piece of code will be executed before any of the test case execute
}
if you need to run that method before the start of all test you should use the annotation #BeforeClass or if you need to execute the same method every time you will execute a test method of that class you must use #Before
f.e
#Before
public void executedBeforeEach() {
//this method will execute before every single test
}
#Test
public void EmptyCollection() {
assertTrue(testList.isEmpty());
}
You can make use of a Test Suite.
The test suite
#RunWith(Suite.class)
#Suite.SuiteClasses({ TestClass.class, Test2Class.class, })
public class TestSuite {
#BeforeClass
public static void setup() {
// the setup
}
}
and, the test classes
public class Test2Class {
#Test
public void test2() {
// some test
}
}
public class TestClass {
#Test
public void test() {
// some test
}
}
Or, you can have a base class which handles the setup
public class TestBase {
#BeforeClass
public static void setup() {
// setup
}
}
and, then the test classes can extend the base class
public class TestClass extends TestBase {
#Test
public void test() {
// some test
}
}
public class Test2Class extends TestBase {
#Test
public void test() {
// some test
}
}
However, this will call the setup method in TestBase for all its subclasses everytime each of them executes.

Why Powermockito invokes my mocked method?

I want to mock private method, which called from my test method, but instead of mocking, PowerMockito invoke toMockMethod, and I get NPE.
toMockMethod is in the same class.
#RunWith(PowerMockRunner.class)
public class PaymentServiceImplTest {
private IPaymentService paymentService;
#Before
public void init() {
paymentService = PowerMockito.spy(Whitebox.newInstance
(PaymentServiceImpl.class));
MockitoAnnotations.initMocks(this);
}
#Test
public void test() throws Exception {
...
PowerMockito.doReturn(mockedReturn)
.when(paymentService,
"toMockMethod",
arg1, arg2);
}
}
Is it normal situation? What a sense to mock method if it has been invoked?
To enable static or non-public mocking with PowerMock for a class, the class should be added to annotation #PrepareForTest. In your case, it should be:
#RunWith(PowerMockRunner.class)
#PrepareForTest(PaymentServiceImpl.class)
public class PaymentServiceImplTest {
private IPaymentService paymentService;
#Before
public void init() {
paymentService = PowerMockito.spy(Whitebox.newInstance
(PaymentServiceImpl.class));
MockitoAnnotations.initMocks(this);
}
#Test
public void test() throws Exception {
...
PowerMockito.doReturn(mockedReturn)
.when(paymentService,
"toMockMethod",
arg1, arg2);
}
}
I'm gonna leave a second answer for my future self here. There's an alternative problem here. If you're calling Static.method make sure "method" is actually defined in Static and not up the hierarchy.
In my case the code called Static.method, but Static extends from StaticParent, and "method" is actually defined in StaticParent.
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticParent.class)
public class YourTestClass {
#Before
public init() {
PowerMockito.mockStatic(StaticParent.class);
when(StaticParent.method("")).thenReturn(yourReturnValue);
}
}
public class ClassYoureTesting {
public someMethod() {
Static.method(""); // This returns yourReturnValue
}

Mocking a static method in abstract class

I have a class A which calls a static method of an abstract class B which throws some exception. I wanted to test for this exception. I am using junit 4.1, mockito 1.9.5 and powermock 1.6.6. The classes are :
abstract class B {
public static void meth(String str) throws SomeException1, SomeException2,SomeException3 {
//some code
}
}
class A{
public void method() throws SomeException1, SomeException2,SomeException3 {
B.meth1("abc");
}
}
I want to test these exceptions and here is my test class
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest(B.class)
class Test throws Throwable {
public void testException(){
PowerMockito.mockStatic(B.class); //Line 6
when(B.meth(Mockito.any(String.class))).thenThrow(new SomeException1(), new SomeException2(), new SomeException3() );
A obj=new A();
obj.method();
}
}
}
While executing this test case I get an exception
org.powermock.api.mockito.ClassNotPreparedException:
The class B not prepared for test.
To prepare this class, add class to the '#PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level.
at org.powermock.api.mockito.expectation.reporter.MockitoPowerMockReporter.classNotPrepared(MockitoPowerMockReporter.java:32)
at org.powermock.api.mockito.internal.mockcreation.MockTypeValidatorFactory$DefaultMockTypeValidator.validate(MockTypeValidatorFactory.java:38)
at org.powermock.api.mockito.internal.mockcreation.AbstractMockCreator.validateType(AbstractMockCreator.java:10)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:56)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:71)
at Test.testException(Test.java:6)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Any suggestion as to why am I getting this ?
You need this: #RunWith(PowerMockRunner.class)
You can use powermock to mock static method.
Code example
#RunWith(PowerMockRunner.class)
public class TestStaticMethodExample {
private SomeClass c = new SomeClass ("g", "123");
#PrepareForTest({ SomeStatic.class })
#Test
public void stubStaticMethod() {
PowerMockito.mockStatic(SomeStatic.class);
PowerMockito.when(SomeStatic.getSummary()).thenReturn(new
SomeClass("t", 9999));
}
}

Java Spring application #autowired returns null pointer exception

Im fairly new to Java Spring IoC and here's my problem
I have a FactoryConfig class with all beans and annotation #Configuration and #ComponentScan written as below.
import org.springframwork.*
#Configuration
#ComponentScan(basePackages="package.name")
public class FactoryConfig {
public FactoryConfig() {
}
#Bean
public Test test(){
return new Test();
}
//And few more #Bean's
}
My Test class has a simple Print method
public class Test {
public void Print() {
System.out.println("Hello Test");
}
}
Now in my Main Class Ive created an ApplicationContentext of FactoryConfig. (I'm expecting all of my #Beans in Factory config will be initialised. However, it returns null when I access the Test class using #Autowired
My Main Class
public class Main {
#Autowired
protected static Test _autoTest;
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ApplicationContext context =
new AnnotationConfigApplicationContext(FactoryConfig.class);
FactoryConfig config = context.getBean(FactoryConfig.class);
config.test().Print();
// _autoTest.Print(); <--- Im getting NULL Pointer Ex here
}
}
What is the correct way to #Autowire and use objects/beans? any clearer explanation would be much appreciated.
Only beans managed by Spring can have #Autowire annotations. Your main class is not managed by Spring: it's created by you and not declared in a Spring context: Spring doesn't known anything about your class, and doesn't inject this property.
You can just access in your main method the Test bean with :
context.getBean(Test.class).Print();
Usually, you get a "bootstrap" from the context, and call this bootstrap to start your application.
Moreover:
On Java, a method shouldn't start with an uppercase. Your Test class should have a print method, not Print.
If you start with Spring, you should maybe try Spring Boot
Spring does not manage your Main class, that's why you are getting Nullpointer Exception.
Using ApplicationContext to load beans, you can get your beans and access Methods as you are already doing -
ApplicationContext context =
new AnnotationConfigApplicationContext(FactoryConfig.class);
FactoryConfig config = context.getBean(FactoryConfig.class);
config.test().Print();
remove the static argument
protected Test _autoTest;
Your class
public class Test {
public void Print() {
System.out.println("Hello Test");
}
}
is not visible to Spring. Try adding an appropriate annotation to it, like #Component.
The reason is that your Main is not managed by Spring. Add it as bean in your configuration:
import org.springframwork.*
#Configuration
#ComponentScan(basePackages="package.name")
public class FactoryConfig {
public FactoryConfig() {
}
#Bean
public Test test(){
return new Test();
}
#Bean
public Main main(){
return new Main();
}
//And few more #Bean's
}
And then you can edit your main() as follows:
public class Main {
#Autowired
protected Test _autoTest;
public static void main(String[] args) throws InterruptedException {
ApplicationContext context =
new AnnotationConfigApplicationContext(FactoryConfig.class);
Test test = context.getBean(Test.class);
Main main = context.getBean(Main.class);
test.Print();
main._autoTest.Print();
}
}

#AfterClass in SpringJUnit4ClassRunner (how to use beans in teardown)

I want to use beans in tear-down method in spring unit test (SpringJUnit4ClassRunner).
But this method (that is annotated with #AfterClass) should be static. What can be the solution?
example:
#RunWith(SpringJUnit4ClassRunner.class)
//.. bla bla other annotations
public class Test{
#Autowired
private SomeClass some;
#AfterClass
public void tearDown(){
//i want to use "some" bean here,
//but #AfterClass requires that the function will be static
some.doSomething();
}
#Test
public void test(){
//test something
}
}
Perhaps you want to use #After instead of #AfterClass. It isn't static.
JUnit uses a new instance for each test method, so in #AfterClass execution the Test instance don't exists and you can't access to any member.
If you really need it, you could add a static member to the test class with the application context and set it manually using an TestExecutionListener
for example:
public class ExposeContextTestExecutionListener extends AbstractTestExecutionListener {
#Override
public void afterTestClass(TestContext testContext) throws Exception {
Field field = testContext.getTestClass().getDeclaredField("applicationContext");
ReflectionUtils.makeAccessible(field);
field.set(null, testContext.getApplicationContext());
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#TestExecutionListeners(listeners={ExposeContextTestExecutionListener.class})
#ContextConfiguration(locations="classpath:applicationContext.xml")
public class ExposeApplicationContextTest {
private static ApplicationContext applicationContext;
#AfterClass
public static void tearDown() {
Assert.assertNotNull(applicationContext);
}
}

Categories

Resources