The code is posted at link
now when i am trying to write the junit for
first case i am getting the error
"need to replay the class B ".
but same junit is working for the second case.
my junit is
#RunWith(PowerMockRunner.class)
public class TestClass {
#Test
public void testDoSomeThing() {
B b = createMock(B.class)
expectNew(b.CallMe()).andReturns(xxx)
A a=new A();
replayAll();
a.doSomething();
verifyAll();
}
}
Here's a solution using EasyMock with PowerMock :
TestClass.java
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({ A.class, B.class })
public class TestClass {
#Test
public void testDoSomeThing() throws Exception {
/* Setup */
B bMock = PowerMock.createMock(B.class);
/* Mocks */
PowerMock.expectNew(B.class).andReturn(bMock).atLeastOnce();
bMock.callMe();
/* Activate */
PowerMock.replayAll();
/* Test */
A cut = new A();
cut.doSomething();
/* Asserts */
PowerMock.verifyAll();
}
}
A.java
public class A {
B b = new B();
public void doSomething() {
b.callMe();
}
}
B.java
public class B {
public void callMe() {
}
}
You forgot to add
#PrepareForTest({A.class, B.class})
This annotation must have the classes you are mocking and the classes that will use these mocks.
Related
The application runs in JEE environment.
I wish inject a Spy into a bean under test.
The Spy object has also some beans inside that should be injected. How can inject mocks of those beans into the Spy?
This is the usecase:
package testinject2;
import javax.inject.Inject;
public class ABean {
#Inject
BBean b;
public void print() {
System.out.println("Hi, I'm ABean");
b.print();
}
}
package testinject2;
import javax.inject.Inject;
public class BBean {
#Inject
CBean c;
public void print() {
System.out.println("Hi, I'm BBean");
c.print();
}
}
package testinject2;
public class CBean {
public void print() {
System.out.println("Hi, I'm CBean");
}
}
package testinject2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
public class ABeanTest {
#Spy
CBean c = new CBean();
#Spy
BBean b = new BBean();
#InjectMocks
ABean beanUnderTest;
#Test
public void test() {
beanUnderTest.print();
}
}
I'm expect to obtain
Hi, I'm ABean
Hi, I'm BBean
Hi, I'm CBean
But instead I have a null ponter exception because CBean is not injected into BBean.
Which is the correct way to Inject a Spy object into another Spy ?
You need to define to which object mocks should be injected via #InjectMocks annotation, but it does not work together with #Spy annotation. See mockito issue.
There is the simplest solution to use Mockito.spy instead of #Spy together with #InjectMocks:
#InjectMocks
BBean b = Mockito.spy(new BBean());
Full test code:
#RunWith(MockitoJUnitRunner.class)
public class ConfigTestObject {
#Spy
CBean c = new CBean();
#InjectMocks
BBean b = Mockito.spy(new BBean());
#InjectMocks
ABean beanUnderTest;
#Test
public void test() {
beanUnderTest.print();
//verify that mocks is working
verify(c, atLeast(1)).print();
verify(b, atLeast(1)).print();
}
}
I read at least 20 posts but still couldn't find the answer. So, posting this question. May be it is answered in some other post, which I couldn't find.
class OuterService {
InnerService innerService;
#Autowired
public void setInnerService(InnerService innerService){
this.innerService = innerService;
}
public void method() {
List<C> listOfC = new ArrayList<C>();
C c = new C();
c.setUserProfiles(someObject);
c = innerService.invokeMethod(String str1,Map map,
String str2, Object obj1, String str3, String str4,
C c, String str5);
c.setCreatedDate(some String value); // Here c comes null while executing jUnits.
listOfC.add(c);
}
}
Here is my Test class:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import com.pogo.service.DeviceRegistrationService;
#SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT")
#SpringBootTest
#RunWith(MockitoJUnitRunner.class)
class ClassOuterServiceTest {
#InjectMocks
OuterService outerService;
#Mock
InnerService innerService;
#Mock C c;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
outerService.setInnerService(innerService);
}
#Test
public void methodTest() {
when(innerService.invokeMethod(Mockito.anyString(),
Mockito.any(Map.class), Mockito.anyString(),Mockito.anyString(),
Mockito.any(PersonSessionToken.class), Mockito.anyString(),Mockito.anyString(), Mockito.anyString(),
Mockito.any(RequestHeader.class),Mockito.any(C.class),
Mockito.anyString() )).thenReturn(c);
doNothing().when(c).invokeCMethod();
outerService.method();
}
}
But I get null inside object c in OuterService.java. Also if I use Matchers.any() or Matchers.anyString() in invokeMethod() then , it shows Matchers exception.
What is the appropriate solution?
You don't need to create the object for OuterService use #InjectMocks annotation and when you use method stubbing use mock objects only. In your program you are creating object for c. Instead of creating object just use #Mock annotation.
When you using Mockito.any() mention the class inside parenthesis. Mockito.any(C.class) like this.
Don't use PowerMockRunner unless you are testing static or final classes.
#SpringBootTest
#RunWith(MockitoJUnitRunner.class)
public class ClassOuterServiceTestC {
#Mock
public InnerService innerService;
#InjectMocks
public OuterService outerService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void methodTest() {
C obj = mock(C.class);
when(innerService.invokeMethod(anyString(), anyMap(), anyString(), any(), anyString(), anyString(), any(TestC.class), anyString()))
.thenReturn(obj);
doNothing().when(obj).setUserProfiles(any(Object.class));
doNothing().when(obj).setCreatedDate(anyString());
outerService.method();
}
}
I am trying to mock a private method using PowerMockito.
Sample code is given below.
Ideally m2() should be returning "from spy method".
Not sure what could be missing.
Please clarify.
Sample.java
import java.io.IOException;
public class Sample {
public void m1(String input) throws IOException {
System.out.println("Sample.m1() BEGIN");
String r = m2(input);
System.out.println("Sample.m1() END--> " + r);
}
private String m2(String s) {
System.out.println("Sample.m2()" + s);
return "From m2 method";
}
}
SampleTest.java
import static org.mockito.Matchers.anyString;
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({ Sample.class })
public class SampleTest {
#Test
public void testM1() throws Exception {
Sample spy = PowerMockito.spy(new Sample());
PowerMockito.doReturn("from spy method").when(spy, "m2", anyString());
Sample sample = new Sample();
sample.m1("Hi m1!!!");
}
}
Output
Sample.m1() BEGIN
Sample.m2()Hi m1!!!
Sample.m1() END--> From m2 method
I needed to call m1() on spy instance instead of sample instance.
Thanks to Giacomo Alzetta for the suggestion.
Modified code:
#Test
public void testM1() throws Exception {
Sample spy = PowerMockito.spy(new Sample());
PowerMockito.doReturn("from spy method").when(spy, "m2", anyString());
spy.m1("Hi m1!!!");
}
I'm developing custom runner of JUnit for internal purposes and, for instance, I've introduced custom annotation for test methods which on applying should make my runner to run method with this annotation after all other test methods without this annotation.
I want to write junit test to verify behavior of my custom runner.
Test class:
public class TestClass {
#Test
#CustomAnnotation
public void test1() {
System.out.println("test1");
}
#Test
public void test2() {
System.out.println("test2");
}
}
An abstract code that will test my runner:
public class MyCustomRunnerTest {
#Test
public void order() throws InitializationError {
// Arrange
// Some code of mocking library might be placed here
// Act
MyCustomRunner runner = new MyCustomRunner(TestClass.class);
runner.run(new RunNotifier());
// Assert
// Here I want to verify that method test1() has been called
// after method test2()
}
}
Is there any mocking libraries that will allow me to perform such verification? Or may be is there any other way to check that?
Why do you not extract the logic that determines the run order of test methods into a separate class or method? This method should return a list of test method names (or other descriptors) in order in which they will run. Then your testing will come down to passing it the test class and asserting that the output is { "test2", "test1" }. No mocking required.
A Better Solution
Use RunListener to log test methods as they are being run by your runner. You of course will have your own MyCustomRunner class, but the rest of the code can stay as in the example below:
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
#RunWith(BlockJUnit4ClassRunner.class)
public class RunnerTest {
// dummy "custom" test runner
public static class MyCustomRunner extends BlockJUnit4ClassRunner {
public MyCustomRunner(Class<?> klass) throws InitializationError {
super(klass);
}
}
public static class TestClass {
#Test
public void test1() {}
#Test
public void test2() {}
}
#Test
public void myCustomRunnerExecutesTestsInOrder() throws InitializationError {
RunNotifier notifier = new RunNotifier();
Collection<String> runTestMethods = new ArrayList<>();
notifier.addListener(new RunListener() {
#Override
public void testStarted(Description description) throws Exception {
runTestMethods.add(description.getMethodName());
}
});
new MyCustomRunner(TestClass.class).run(notifier);
// assert that the collection contains methods names in the specified order
assertThat(runTestMethods, contains("test1", "test2"));
}
}
In eclipse, with JUnit 4, you can right click a project or package and click Run as JUnit Test, and it will run all the JUnit tests within that grouping. Is there a way to do this same thing from within the code?
You can use packages in junit such as JUnitCore like this:
public static void main(String[] args){
List tests = new ArrayList();
tests.add(TestOne.class);
tests.add(TestTwo.class);
for (Class test : tests){
runTests(test);
}
}
private static void runTests(Class test){
Result result = JUnitCore.runClasses(test);
for (Failure failure : result.getFailures()){
System.out.println(failure.toString());
}
}
Use JUnit Suite:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
#RunWith(Suite.class)
// Put your Test Case Class here
#Suite.SuiteClasses({
JunitTest1.class,
JunitTest2.class,
JunitTest3.class
})
public class JunitTestSuite {}
Then create a main method to run it.
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class JunitTestSuiteRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(JunitTestSuite.class);
for (Failure fail : result.getFailures()) {
System.out.println(fail.toString());
}
if (result.wasSuccessful()) {
System.out.println("All tests finished successfully...");
}
}}
JUnit provides the test Suite. Give that a try.
[...]
public class TestCaseA {
#Test
public void testA1() {
// omitted
}
}
[...]
public class TestCaseB {
#Test
public void testB1() {
// omitted
}
}
[...]
#RunWith(value=Suite.class)
#SuiteClasses(value = {TestCaseA.class})
public class TestSuiteA {
}
[...]
#RunWith(value=Suite.class)
#SuiteClasses(value = {TestCaseB.class})
public class TestSuiteB {
}
[...]
#RunWith(value = Suite.class )
#SuiteClasses(value = {TestSuiteA.class, TestSuiteB.class})
public class MasterTestSuite{
}