How to mock a void method with no arguments? - junit

For Example:
Class A{
string s = null;
public void method(){
s="Sample String";
}
}
I have a void method with similar scenario. How can I test such void method?

With void methods you should test the interaction with its dependent objects within the void method. I think a void method with no argument is rarely useful to test (but if you have a valid use case, please add it to your question). I provided you a simple example for a method with an argument but void as a return type:
public class A {
private DatabaseService db;
private PaymentService payment;
// constructor
public void doFoo() {
if(n < 2) {
db.updateDatabase();
} else {
payment.payBill();
}
}
}
And the unit test for this can look like the following
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
DatabaseService db;
#Mock
PaymentService payment;
#Test
public void testDoFooWithNGreaterTwo() {
A cut = new A(db, payment); // cut -> class under test
cut.doFoo(3);
verify(payment).payBill(); // verify that payment was called
}
#Test
public void testDoFooWithNLessThanTwo() {
A cut = new A(db, payment); // cut -> class under test
cut.doFoo(1);
verify(db).updateDatabase(); // verify that db was called
}
}

Related

Junit Test (Mockito, PowerMock) a class with void method and private value

some sample code like:
(I just added some more details)
public class A {
#Autowired
private Data data;
#RequestMapping(value="/Boo", method = RequestMethod.GET)
public void Boo(){
data.someMethod();
}
}
I want to test the someMethod() is run or not.
I have tried #First answer but got some error message like below:
java.lang.AbstractMethodError: org.powermock.api.mockito.internal.exceptions.StackTraceCleanerProvider$1.isIn(Ljava/lang/StackTraceElement;)Z
at org.mockito.internal.exceptions.stacktrace.StackTraceFilter.filter(StackTraceFilter.java:33)
at org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter.filter(ConditionalStackTraceFilter.java:23)
at org.mockito.exceptions.base.MockitoException.filterStackTrace(MockitoException.java:44)
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#InjectMocks
private A a;
#Spy
private Data data;
#Test
public void test() {
// execute
this.a.Boo();
// verify
Mockito.verify(this.data).someMethod();
}
}

Mocking an injected object in a method return and UnsupportedOperationException method

I have a class that returns an injected object using Mockito. Everytime I test it, it returns a bull. How would I properly test it to return the correct object?
My class to test:
#Component
public class CarImpl {
#Inject
private Engine v6EngineImpl;
public Engine getEngine() {
return v6EngineImpl;
}
public Exhaust getExhaust() {
throw new UnsupportedOperationException("unsupported");
}
}
Tests:
#RunWith(MockitoJUnitRunner.class)
public class CarTest {
#InjectMocks
private CarImpl carImpl;
#Mock
private Engine v6EngineImpl;
#Test
public void testGetEngine(){
Engine v6EngineImpl = mock(V6EngineImpl.class);
Engine engine = carImpl.getEngine();
// always returns a bull no matter what, how to mock inject.
//return object correctly?
Assert.assertNotNull(engine);
}
#Test
public void testGetExhaust() {
// how to test thrown exception?
}
}
Thanks, I am not too familiar thanks
Try this:
#RunWith(MockitoJUnitRunner.class)
public class CarTest {
#InjectMocks
private CarImpl carImpl;
#Mock
private Engine v6EngineImpl;
#Test
public void testGetEngine(){
Engine engine = carImpl.getEngine();
//engine is the mock injected to CarImpl
Assert.assertNotNull(engine);
Assert.assertSame(engine,v6EngineImpl);
}
#Test(expected=UnsupportedOperationException.class)
public void testGetExhaust() {
carImpl.getExhaust();
}
}

Test play controller with session data

I have a simple controller test.
route(fakeRequest(routes.Accounts.accounts()).session("sessionref","fakeSession"));
Secured Autheticator looks like this:
public class Secured extends play.mvc.Security.Authenticator {
#Inject
AuthServices authService;
public String getUsername(Http.Context context) {
return authService.checkSession(context);
}
#Override
public Result onUnauthorized(Http.Context context) {
return ok(index.render(formFactory.form(forms.LoginForm.class)));
}
}
How can i mock authService?
I tried to mock with guice bind but this method don't work
#Before
public void setup() {
startPlay();
MockitoAnnotations.initMocks(this);
Module testModule = new AbstractModule() {
#Override
public void configure() {
bind(AuthServices.class)
.toInstance(authServices);
}
};
GuiceApplicationBuilder builder = new GuiceApplicationLoader()
.builder(new play.ApplicationLoader.Context(Environment.simple()))
.in(Mode.TEST)
.overrides(testModule);
Guice.createInjector(builder.applicationModule()).injectMembers(this);
}
You can read this for testing Play controllers and follow this example for testing with Guice.
For your case it is something like this:
public class MyTest extends WithApplication {
#Mock
AuthServices mockAuthService;
#Override
protected Application provideApplication() {
return new GuiceApplicationBuilder()
.overrides(bind(CacheProvider.class).toInstance(mockAuthService))
.in(Mode.TEST)
.build();
}
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testAccounts() {
running(provideApplication(), () -> {
RequestBuilder testRequest = Helpers.fakeRequest(controllers.routes.Accounts.accounts()).session("sessionref","fakeSession");
Result result = route(testRequest);
//assert here the expected result
});
}
}

Junits for classes extending QuartzJobBean

I have a Java class that extends QuartzJobBean and has been scheduled at a specific time through out the day.
public class ServiceJob extends QuartzJobBean {
#Override
protected void executeInternal(JobExecutionContext context) {
}
Can someone please help me understand how to create a Junit test case for this. How do I invoke the executeInternal() method in the test case.
Thanks for any help on this.
I create a solution for my working project, i agree to adarshdatt to solve it via importing config file that defined the bean. You can find a good tutorial about it at this blog post,
For future use I want to show how i solve it with Mocking, just use Mockito #Mock annotation with this way :
SessionConfirmationJob.java
public class SessionConfirmationJob extends QuartzJobBean {
#Autowired
private SessionService sessionService;
#Autowired
private TransactionService transactionService;
#Autowired
private SystemLogger systemLogger;
public static final String TOKEN = "token";
private SpringInjectQuartzJobBean springInjectQuartzJobBean;
public SessionService getSessionService() {
return sessionService;
}
public void setSessionService(SessionService sessionService) {
this.sessionService = sessionService;
}
public TransactionService getTransactionService() {
return transactionService;
}
public void setTransactionService(TransactionService transactionService) {
this.transactionService = transactionService;
}
public void setSpringInjectQuartzJobBean(SpringInjectQuartzJobBean springInjectQuartzJobBean) {
this.springInjectQuartzJobBean = springInjectQuartzJobBean;
}
public SystemLogger getSystemLogger() {
return systemLogger;
}
public void setSystemLogger(SystemLogger systemLogger) {
this.systemLogger = systemLogger;
}
#Override
protected void executeInternal(JobExecutionContext paramJobExecutionContext) throws JobExecutionException {
springInjectQuartzJobBean = new SpringInjectQuartzJobBean();
springInjectQuartzJobBean.injectQuartzJobToSpringApplicationContext(this);
String token = paramJobExecutionContext.getMergedJobDataMap().getString(TOKEN);
Session session = sessionService.getByToken(token);
if (session != null) {
if (session.getPaymentConfirmation() == null || session.getPaymentConfirmation() != true) {
Transaction transactionToBeRolledBack = transactionService.getRollBackTransactionOfPayment(session);
if (transactionToBeRolledBack != null) {
try {
transactionService.rollBackTransaction(transactionToBeRolledBack);
} catch (IOException e) {
systemLogger.logException("Exception while rolling back transaction", e);
}
session = sessionService.getByToken(token);
session.setStatus(SessionStatus.FI);
session.setPaymentConfirmation(false);
sessionService.saveOrUpdate(session);
}
}
}
}
}
This is the method i should write test and this is the testing class.
SessionConfirmationJobTest.java
#RunWith(MockitoJUnitRunner.class)
public class SessionConfirmationJobTest {
#Mock
private SessionService sessionService;
#Mock
private TransactionService transactionService;
#Mock
private JobExecutionContext ctx;
#Mock
private SpringInjectQuartzJobBean springInjectQuartzJobBean;
private JobDataMap mergedJobDataMap = new JobDataMap();
#Mock
private Scheduler scheduler;
private SessionConfirmationJob sessionConfirmationJob;
private String token = "payment token";
#Before
public void setUp() throws SchedulerException {
mergedJobDataMap.put(SessionConfirmationJob.TOKEN, token);
when(ctx.getMergedJobDataMap()).thenReturn(mergedJobDataMap);
when(ctx.getScheduler()).thenReturn(scheduler);
when(scheduler.getContext()).thenReturn(null);
sessionConfirmationJob = new SessionConfirmationJob();
sessionConfirmationJob.setSessionService(sessionService);
sessionConfirmationJob.setTransactionService(transactionService);
sessionConfirmationJob.setSpringInjectQuartzJobBean(springInjectQuartzJobBean);
}
/**
* Test payment confirmation when we have false payment confirmation
*
* #throws JobExecutionException
*/
#Test
public void testPaymentRollBackForFalseConfirmation() throws IOException, JobExecutionException {
Session session = new Session();
session.setStatus(SessionStatus.AC);
session.setPaymentConfirmation(false);
Transaction transaction = new Transaction();
transaction.setSession(session);
transaction.setType(TransactionType.SALE);
transaction.setStatus(TransactionStatus.AP);
when(sessionService.getByToken(token)).thenReturn(session);
when(transactionService.getRollBackTransactionOfPayment(session)).thenReturn(transaction);
when(transactionService.rollBackTransaction(transaction)).thenReturn(true);
sessionConfirmationJob.execute(ctx);
Assert.assertEquals(SessionStatus.FI, session.getStatus());
Assert.assertFalse(session.getPaymentConfirmation());
verify(sessionService).saveOrUpdate(session);
}
}
Before mock the Schedular object i get NullPointerException at pvs.addPropertyValues(context.getScheduler().getContext()); after i mock schedular it is solved and my test is passed. Below is the
org.springframework.scheduling.quartz.QuartzJobBean#execute(JobExecutionContext context) method. Actually executeInternal is protected so we must call execute method first then execute method is call executeInternal which is override at your implemented Job class(my demo it is SessionConfirmationJob).
QuartzJobBean.java
public abstract class QuartzJobBean implements Job {
/**
* This implementation applies the passed-in job data map as bean property
* values, and delegates to {#code executeInternal} afterwards.
* #see #executeInternal
*/
#Override
public final void execute(JobExecutionContext context) throws JobExecutionException {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValues(context.getScheduler().getContext());
pvs.addPropertyValues(context.getMergedJobDataMap());
bw.setPropertyValues(pvs, true);
}
catch (SchedulerException ex) {
throw new JobExecutionException(ex);
}
executeInternal(context);
}
/**
* Execute the actual job. The job data map will already have been
* applied as bean property values by execute. The contract is
* exactly the same as for the standard Quartz execute method.
* #see #execute
*/
protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;
}
If you have question don't hesitate to ask me via comments.

Run a list of jUnit runners

I have some test suites that in essence looks like
#Test
public void test1_2() {
test(1,2);
}
#Test
public void test1_3() {
test(1,3);
}
#Test
public void test4_5() {
test(4,5);
}
#Test
public void test4_9() {
test(4,9);
}
// and so forth
private void test(int i, int j) throws AssertionError{
// ...
}
(This is not the actual tests, but the essence, each #Test method only calls one method)
So my thinking was that I could use #RunWith for a custom BlockJUnit4ClassRunner which accepts a List of jUnit Runners.
How would this be achived? Or is there a better way to do it?
Why not use #Parameter ?
#RunWith(Parameterized.class)
public class YourTest{
private int i;
private int j;
public Parameter(int i, int j) {
this.i= i;
this.j= j;
}
#Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][] { { 1, 2 }, { 1,3 }, { 4,5 }, { 4,9 } };
return Arrays.asList(data);
}
#Test
public void test() throws InterruptedException {
//use i & j
}
}
This looks to me like something that should be done with Theories. Otherwise, you could use Enclosed to have multiple inner classes each with its own runner.