My following Unit test is failing.
I'm getting an error The class com.xyz.sys.PluginManager not prepared for test.
// #RunWith(PowerMockRunner.class)
#RunWith(GlideUiRunner.class)
public class TestClass extends BaseITClass {
private static final String PLUGIN_MESSAGE = "texttt";
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
// PowerMockito.mockStatic(RecordCache.class);
}
#Test
public void testUpgradeMonitorDontShowAtfPluginWarningMessage() {
open(UPGRADE_PAGE);
String actualMsg = findElement(By.xpath("//div[#ng-if='divElementName']")).getText();
PowerMockito.mockStatic(PluginManager.class);
PowerMockito.when(PluginManager.isActive("pluginName")).thenReturn(true);
Assert.assertFalse(actualMsg.contains(PLUGIN_MESSAGE));
}
}
Any suggestions where the issue is?
Note: I need to use GlideUiRunner.class.. Can't remove that.
Related
I have a class name ServiceLocator
public class ServiceLocator implements ApplicationContextAware {
private transient ApplicationContext _applicationContext;
private static ServiceLocator _instance = new ServiceLocator();
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
_instance._applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return _instance._applicationContext;
}
public static Object findService(String serviceName) {
return _instance._applicationContext.getBean(serviceName);
}
}
I am trying to use that class to find Service into Approver class methods
public class ApproverService extends AbstractDataService implements IApproverService {
public void updateCompletedInboxStatus(String status) {
IInboxService inboxService = (IInboxService)ServiceLocator.findService("inboxService");
InboxItem inboxItem = inboxService.getInboxItem("test");
inboxItem.setWorkItemStatus(status);
inboxService.saveInboxItem(inboxItem);
}
}
With that code i am trying to write Junit with PowerMockRunner
#RunWith(PowerMockRunner.class)
#PrepareForTest({ApproverService.class})
public class ApproverServiceTest {
#InjectMocks
ApproverService approverService;
#Mock
IInboxService inboxService;
#Mock
ServiceLocator serviceLocator;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void updateCompletedInboxStatus() {
RequestAccessHeader reqHdr = new RequestAccessHeader();
reqHdr.setRequestStatus(AccessConstants.REQ_STATUS_HOLD_INT);
String status = "test";
PowerMockito.mockStatic(ServiceLocator.class);
when(serviceLocator.findService("inboxService")).thenReturn(inboxService);
approverService.updateCompletedInboxStatus(status);
}
}
But I am getting null pointer
java.lang.NullPointerException
at com.alnt.fabric.common.ServiceLocator.findService(ServiceLocator.java:25)
at com.alnt.access.approver.service.ApproverServiceTest.updateCompletedInboxStatus(ApproverServiceTest.java:80)
Please help me to find the solution for that issue.
The static method is obviously not mocked.
The problem is most probably because you haven't add the to-be-mocked class in #PrepareForTest
Change it to #PrepareForTest({ApproverService.class, ServiceLocator.class})
Off-topics:
Although it compiles, calling static method by instance reference is not a good practice. Therefore the line should be when(ServiceLocator.findService(...)).thenReturn(inboxService).
Another problem is, you tried to use Singleton pattern but in wrong way. A singleton is suppose to return you an instance so the caller can call its instance method. Your findService is preferably an instance method and to be called as ServiceLocator.getInstance().findService(...). To further improve, unless you really need it to be a singleton, you should make it a normal object instance and inject to objects that need it (given you are already using Spring, I see no reason making a Singleton)
The setup for the static method is not mocked correctly
#RunWith(PowerMockRunner.class)
#PrepareForTest({ServiceLocator.class}) //Prepare static class for mock
public class ApproverServiceTest {
#Mock
IInboxService inboxService;
#Mock
InboxItem item;
#InjectMocks
ApproverService approverService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void updateCompletedInboxStatus() {
//Arrange
String status = "test";
PowerMockito.mockStatic(ServiceLocator.class);
when(ServiceLocator.findService("inboxService")) //<-- NOTE static call
.thenReturn(inboxService);
when(inboxService.getInboxItem("test")).thenReturn(item);
//Act
approverService.updateCompletedInboxStatus(status);
//...
}
}
Reference Mocking Static Method
The subject under test should actually be refactored to avoid the service locator anit-pattern / code smell and should follow explicit dependency principle via constructor injection.
public class ApproverService extends AbstractDataService implements IApproverService {
private IInboxService inboxService;
#Autowired
public ApproverService(IInboxService inboxService){
this.inboxService = inboxService;
}
public void updateCompletedInboxStatus(String status) {
InboxItem inboxItem = inboxService.getInboxItem("test");
inboxItem.setWorkItemStatus(status);
inboxService.saveInboxItem(inboxItem);
}
}
That way the subject class is genuine about what it needs to perform its function correctly,
And the test can then be refactored accordingly
#RunWith(PowerMockRunner.class)
public class ApproverServiceTest {
#Mock
IInboxService inboxService;
#Mock
InboxItem item;
#InjectMocks
ApproverService approverService;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void updateCompletedInboxStatus() {
//Arrange
String status = "test";
when(inboxService.getInboxItem("test")).thenReturn(item);
//Act
approverService.updateCompletedInboxStatus(status);
//...
}
}
I am trying to unit test a method, which has different branches depending upon the value of an object that is created inside it. The below code demonstrates it.
public class AClass {
public void method2() {
//Some code goes here
}
public void method1(BClass bObject) {
C_Class cObject = bObject.someMethodThatReturnsC();
if(cObject != null) {
method2();
method2();
}
}}
Below is the TestClass:
public class AClassTest {
#InjectMocks
AClass AClassSpy;
#Mock
BClass b_objectMock;
#Mock
C_Class c_objectMock;
#BeforeMethod
public void beforeMethod() {
AClassSpy = spy(new AClass());
MockitoAnnotations.initMocks(this);
}
public void method1Test () {
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC());
AClassSpy.method1(b_objectMock);
verify(AClassSpy, times(2).method2();
}
}
However, it always FAILS, since the c_objectMock is always null. What do I do to tell Mockito to not to return a null object?
It works good, just use #Before annotation from junit, not #BeforeMethod, and mark your test method like #Test and remove second bracket from
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC())<-this one;
and add bracket at verify:
verify(AClassSpy, times(2)<-here.method2();
And just take care of your code!
This should work:
public class AClassTest {
#InjectMocks
private AClass AClassSpy;
#Mock
private BClass b_objectMock;
#Mock
private C_Class c_objectMock;
#Before
public void beforeMethod() {
AClassSpy = spy(new AClass());
MockitoAnnotations.initMocks(this);
}
#Test
public void method1Test() {
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC();
AClassSpy.method1(b_objectMock);
verify(AClassSpy, times(2)).method2();
}
}
Instead of before method you can use annotation #RunWith. It looks clearly:
#RunWith(MockitoJUnitRunner.class)
public class AClassTest {
#Spy
#InjectMocks
private AClass AClassSpy;
#Mock
private BClass b_objectMock;
#Mock
private C_Class c_objectMock;
#Test
public void method1Test() {
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC();
AClassSpy.method1(b_objectMock);
verify(AClassSpy, times(2)).method2();
}
}
You are having this behaviour because you are not mocking property the call to someMethodThatReturnsC.
It should be:
doReturn(c_objectMock).when(b_objectMock).someMethodThatReturnsC();
I have this code in my Subject Under Test:
public class Widget {
private Set<Thing> things;
public Set<Thing> getThings() { return things; }
public void setThings(Set<Thing> things) { this.things = things; }
public void performAction(PerformingVisitor performer) {
for (Thing thing: getThings())
{
thing.perform(performer);
}
}
}
My JUnit/Mockito test looks like:
#RunWith(MockitoJUnitRunner.class)
public class WidgetTest {
#Mock private PerformingVisitor performer;
#Mock private Thing thing;
#InjectMocks private Widget widget;
#Before
public void setUp() throws Exception {
Set<Thing> things = new HashSet<Thing>();
things.add(thing);
widget.setThings(things);
MockitoAnnotations.initMocks(this);
}
#Test
public void shouldPerformThing() {
Mockito.when(thing.perform(Mockito.any(PerformingVisitor.class))).thenReturn(true);
widget.performAction(performer);
Mockito.verify(thing).perform(Mockito.any(PerformingVisitor.class));
}
}
However, this gives me the error:
Wanted but not invoked:
thing.perform(<any>);
-> at com.myclass.ThingTest.shouldPerformThing(WidgetTest.java:132)
I've verified that the code enters the for loop and should be calling the actual thing.perform(performer); line, but my mock does not seem to be recording a call.
I think you need initMocks before the mock injection.
Could you try to change your setUp method for this:
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
Set<Thing> things = new HashSet<Thing>();
things.add(thing);
widget.setThings(things);
}
Hope it works
From the MockitoJUnitRunner javadoc:
Initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary.
So, if you remove
MockitoAnnotations.initMocks(this)
from your setUp method, the test pass.
I m using mockito for junit. I have doubt while creating mock of object.
I have class called DBConnect. Where I need database properties like dbname, credentials etc.
This class is used by PatientDetails. Now when I am writing junit for PatientDetails. So I am using following code.
#RunWith(MockitoJUnitRunner.class)
public class PatientDetailsTest {
#Mock
DBConnect dbConnect
#Before
public void setUp()
{
PatientDetails testClass = new PatientDetails();
testClass.setDBConnect(dbConnect);
}
}
I can not get correct result with this.
You code seems fine to me. I've extended it slightly to include a test, so that it can be run. This works fine:
#RunWith(MockitoJUnitRunner.class)
public class PatientDetailsTest {
#Mock
DBConnect dbConnect;
#Before
public void setUp() {
when(dbConnect.sayHello()).thenReturn("works for me");
PatientDetails testClass = new PatientDetails();
testClass.setDBConnect(dbConnect);
}
#Test
public void testname() throws Exception {
System.out.println("foo");
}
private static interface DBConnect {
String sayHello();
}
private static class PatientDetails {
public void setDBConnect(DBConnect dbConnect) {
System.out.println(dbConnect.sayHello());
}
}
}
Output:
works for me
foo
I want to get currently executing test method in #Before so that I can get the annotation applied on currently executing method.
public class TestCaseExample {
#Before
public void setUp() {
// get current method here.
}
#Test
#MyAnnotation("id")
public void someTest {
// code
}
}
try TestName rule
public class TestCaseExample {
#Rule
public TestName testName = new TestName();
#Before
public void setUp() {
Method m = TestCaseExample.class.getMethod(testName.getMethodName());
...
}
...
Evgeniy pointed to the TestName rule (which i'd never heard of - thanks, Evgeniy!). Rather than using it, i suggest taking it as a model for your own rule which will capture the annotation of interest:
public class TestAnnotation extends TestWatcher {
public MyAnnotation annotation;
#Override
protected void starting(Description d) {
annotation = d.getAnnotation(MyAnnotation.class);
}
}