How to test static method invokation in Android? - java

I have an Android activity and I want to write a unit test, which verifies that in onResume the activity checks whether the Internet is available.
public class MyActivity {
#Override
protected void onResume() {
super.onResume();
setContentView(R.layout.connect_to_server);
// Internet availability check
final IInternetAvailabilityChecker checker = InternetAvailabilityChecker.create(this);
if (!checker.isInternetAvailable())
{
Utils.showMessageBox(this, R.string.app_name,
R.string.internet_not_available);
return;
}
In the test, I want to verify that MyActiviy.onResume calls the InternetAvailabilityChecker.create method.
How can I do it (with any free mocking framework compatible with Android) ?
I tried to use PowerMock for this (see example below), but when I try to run the test, I get errors like MockTest.java:7: package org.powermock.core.classloader.annotations does not exist.
Maven:
<properties>
<powermock.version>1.5.1</powermock.version>
</properties>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
Unit test:
#RunWith(PowerMockRunner.class)
#PrepareForTest( { InternetAvailabilityChecker.class })
public class MyActivityPowerMockTest {
#Test
#Ignore
public void test()
{
final IInternetAvailabilityChecker checker = mock(IInternetAvailabilityChecker.class);
when(checker.isInternetAvailable()).thenReturn(false);
mockStatic(InternetAvailabilityChecker.class);
expect(InternetAvailabilityChecker.create(any(Activity.class))).andReturn(checker);
replay(InternetAvailabilityChecker.class);
final MyActivity objectUnderTest = new MyActivity();
objectUnderTest.onResume();
// Verify that the method InternetAvailabilityChecker.create was called
verify(InternetAvailabilityChecker.class);
// TODO: Verify that Utils.showMessageBox has been invoked
}
}

You appear to be missing a Maven dependency. According to this query the annotations are supplied by:
org.powermock / powermock-core
org.powermock / powermock-easymock-single-jar-release-full
org.powermock / powermock-mockito-single-jar-release-full

Related

How to Mock /actuator/health in UnitTest

I'm intercepting the actuator/health endpoints in a custom Service by Auto-wiring the HealthContributor interface:
#Service
public class HealthCheckServiceImpl implements HealthIndicator{
#Autowired HealthContributor[] healthContributors;
#Override
public Health health() {
Map<String, String> components = new HashMap<String, String>();
for (HealthContributor healthContributor : healthContributors) {
String componentName =
healthContributor
.getClass()
.getSimpleName()
.replace("HealthIndicator", "")
.replace("HealthCheckIndicator", "");
String status = ((HealthIndicator) (healthContributor)).health().getStatus().toString();
components.put(componentName, status);
}
String healthComponentAsString = components.keySet().stream()
.map(key -> key + "->" + components.get(key))
.collect(Collectors.joining(", "));
Boolean isComponentDown = components.containsValue("DOWN");
if (Boolean.TRUE.equals(isComponentDown)) {
return Health.down().withDetail("Status: One of the API component is down. ","").build();
} else {
return Health.up().withDetail("Status: All API components are Up. ", "").build();
}
}
My question is, How can I mock the status of the components in order to test the health() method behavior.
I have tried
#MockBean
#Qualifier("pingHealthContributor") // intercepting just one component instead of
// HealthContributor[]
HealthContributor healthContributors;
but when I try to use Mockito. when() as follows:
String status="UP";
when(((HealthIndicator) (healthContributors)).health().getStatus().toString()).thenReturn(status);
I get the following error :
java.lang.ClassCastException: class org.springframework.boot.actuate.health.HealthContributor$MockitoMock$297980690 cannot be cast to class org.springframework.boot.actuate.health.HealthIndicator (org.springframework.boot.actuate.health.HealthContributor$MockitoMock$297980690 and org.springframework.boot.actuate.health.HealthIndicator are in unnamed module of loader 'app')
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

How can i make DateUtil throw an exception?

#Override
public void contextDestroyed(ServletContextEvent sce) {
try{
DateUtil.clean();
}catch(Exception e){
LOGGER.error("MyServletContextListener contextDestroyed error: ", e);
}
I am doing unit testing on the above piece of code, and am trying to get 100% line coverage by hitting the Exception clause, however, i cant seem to make it work with my implementation. Would appreciate any help yall. Please look below for my implementation.
#Test (expected= Exception.class)
public void test_contextDestroyed_Exception() {
DateUtil wrapper = Mockito.spy(new DateUtil());
Exception e = mock(Exception.class);
when(wrapper).thenThrow(e);
Mockito.doThrow(e)
.when(myServletContextListener)
.contextDestroyed(sce);
myServletContextListener.contextDestroyed(sce);
}
Since DateUtil.clean() is a static method, you can't mock it with Mockito.
You need to use PowerMockito instead:
<properties>
<powermock.version>1.6.6</powermock.version>
</properties>
<dependencies>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Check official PowerMock documentation for version compatibility with JUnit and Mockito.
Once you did that, you should add the following to your test class:
#RunWith(PowerMockRunner.class) //<-- this says to JUnit to use power mock runner
#PrepareForTest(DateUtil.class) //<-- this prepares the static class for mock
public class YourTestClass {
#Test(expected = Exception.class)
public void test_contextDestroyed_Exception() {
PowerMockito.mockStatic(DateUtil.class);
when(DateUtil.clean()).thenThrow(new Exception("whatever you want"));
//prepare your test
//run your test:
myServletContextListener.contextDestroyed(sce);
}
}
you can use mockito-inline artifact from Mockito to test static methods and follow the below approach,
try (MockedStatic<DateUtil> utilities = Mockito.mockStatic(DateUtil.class)) {
utilities.when(DateUtil::clean).thenThrow(Exception.class);
// assert exception here
}
for more info,
https://frontbackend.com/java/how-to-mock-static-methods-with-mockito

How to write assertTimeoutPreemptively (JUnit 5) in JUnit 4?

Till now I was working on JUnit 5 and now I have to work on an old system with JUnit 4 and I cannot update JUnit 5 there. I have a test in JUnit 5 that I have to write in JUnit 4 but I am not sure how it will work or how to write? Below is the JUnit 5 version of the test.
#AfterEach
void afterEach() throws Exception {
// Bleed off any events that were generated...
assertTimeoutPreemptively(ofMillis(MESSAGE_CLEARING_TIMEOUT_MS), () -> {
boolean tryAgain = true;
while (tryAgain) {
try {
final IMessageFacade message = messageConsumer.receiveMessage(MESSAGE_TIMEOUT_MS);
message.acknowledge();
} catch (MessagingException e) {
tryAgain = false;
}
}
});
broker.stop();
}
In the test, I am using assertTimeoutPreemptively() and am not sure how to convert it to JUnit 4. I tried putting a timeout which is a global timeout in JUnit 4 but that didn't work. Any guidance in terms of writing above #AfterEach condition with JUnit 4?
Shouldn't assertions run only once? Finding asserts in test teardown is somehow surprising. Consider to make your assertions part of your tests.
In JUnit 5 this looks like:
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
public class TimeoutJUnit5Test {
#Test #Timeout(value = 10, unit = MILLISECONDS)
void junitFiveTimeout() {
// ...
}
}
and in JUnit 4:
import org.junit.Test;
public class TimeoutJUnit4Test {
#Test(timeout = 10)
public void junitFourTimeout() {
// ...
}
}
What's stopping you from using both versions of JUnit? (pom.xml):
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
Last option would be to simply copy / adapt the behaviour from the new JUnit 5 assertTimeoutPreemptively() to you own project.

Mockito.spy VerifyError: Constructor must call super() or this()

I am trying to execute simple test case, but getting an error. Below is my test case :
#Rule
public AemContext context = new AemContext();
#Test
public void test() throws Exception {
Resource currentResource = context
.create()
.resource("/content/app/en-us/page", "jcr:title", "Title Page", "width", "5","height","9");
inheritanceValueMap = Mockito.spy(new HierarchyNodeInheritanceValueMap(currentResource));
Assert.assertThat(inheritanceValueMap.getInherited("width", StringUtils.EMPTY), Is.is("5"));
}
Error I am getting is :
java.lang.VerifyError: (class: com/day/cq/commons/ValueMapWrapper, method: signature: (Lorg/apache/sling/api/resource/ValueMap;)V) Constructor must call super() or this()
Any solution to this?
This issue usually comes when we use below dependency of uber jar :
<dependency>
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<version>6.2.0</version>
<classifier>obfuscated-apis</classifier>
<scope>provided</scope>
</dependency>
Try changing the dependency classifier to apis , as shown below:
<dependency>
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<version>6.2.0</version>
<classifier>apis</classifier>
<scope>provided</scope>
</dependency>

PUT and POST not working from J2SE platform (RESTLET Version 3.0-M1)

I'm working on a project with GWT and J2SE clients. The GWT part is working great, but now there are problems with the J2SE client;
"The server understands the content type of the request entity and the
syntax of the request entity is correct but was unable to process the
contained instructions"
"The serialized representation must have this media type:
application/x-java-serialized-object or this one:
application/x-java-serialized-object+xml"
This code was working some months/versions ago... Both PUT and POST produce this error while GET is working. Whats wrong here?
Here's a really simple test case
// Shared Interface
public interface J2SeClientServerResourceInt
{
#Post("json")
public J2seStatusDto postJ2seStatus(J2seStatusDto pJ2seStatusDto);
}
// Java Bean
public class J2seStatusDto implements Serializable
{
private static final long serialVersionUID = 6901448809350740172L;
private String mTest;
public J2seStatusDto()
{
}
public J2seStatusDto(String pTest)
{
setTest(pTest);
}
public String getTest()
{
return mTest;
}
public void setTest(String pTest)
{
mTest = pTest;
}
}
// Server
public class J2seServerResource extends ClaireServerResource implements J2SeServerResourceInt
{
#Override
public J2seStatusDto postJ2seStatusDto(J2seStatusDto pJ2seStatusDto)
{
return pJ2seStatusDto;
}
}
// J2SE Client
public class ClaireJsSeTestClient
{
public static void main(String[] args)
{
Reference lReference = new Reference("http://localhost:8888//rest/j2se");
ClientResource lClientResource = new ClientResource(lReference);
lClientResource.accept(MediaType.APPLICATION_JSON);
J2SeServerResourceInt lJ2SeServerResource = lClientResource.wrap(J2SeServerResourceInt.class);
J2seStatusDto lJ2seStatusDto = new J2seStatusDto("TEST");
J2seStatusDto lJ2seResultDto = lJ2SeServerResource.postJ2seStatusDto(lJ2seStatusDto);
}
}
// Maven J2Se Client
<dependencies>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>3.0-M1</version>
</dependency>
</dependencies>
// Maven GAE Server
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.servlet</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.gwt</artifactId>
<version>3.0-M1</version>
</dependency>
<dependency>
<groupId>org.restlet.gwt</groupId>
<artifactId>org.restlet</artifactId>
<version>3.0-M1</version>
<scope>compile</scope>
</dependency>
Thierry Boileau fixed our problem (mistake);
https://github.com/restlet/restlet-framework-java/issues/1029#issuecomment-76212062
Due to the constraints of the GAE platform (there is no support of chunked encoding) you have to specify that the request entity is buffered first;
cr.setRequestEntityBuffering(true);
Thanks for the great support at restlet.com

Categories

Resources