Reputation: 303
Consider I have a class Tournament
with methods register()
and isAlreadyRegistered()
. Below is the sample code.
public class Tournament {
private boolean register(String teamName) {
if(!isAlreadyRegistered(teamName)) {
// register team
return True;
}
return False;
}
private boolean isAlreadyRegistered(String teamName) {
// Check if team is already registered, involves DB calls
}
public static void main(String[] args) throws Exception {
Tournament tournament = new Tournament();
tournament.register("e-LEMON-ators");
}
}
I have a Java test-case which calls main method of class Tournament
, which leads to call to
register()
method and register()
method calls isAlreadyRegistered()
. Consider below code:
@Test
public void testTournament() {
try {
Tournament.main(args);
} catch (Exception e) {
fail();
}
}
I want to mock isAlreadyRegistered()
, maybe using Mockito, so it always returns True
Note: The example is only for demonstration purpose and I cannot modify the Tournament class. Modifications can only be made in Test case. Testing register()
separately is not an option (call has to be made through main method)
EDIT: I cannot create object for class Tournament
i.e. I can interact with the class only through main()
method
Upvotes: 0
Views: 2401
Reputation: 678
Try moving the actual register method call into a different method so that you can pass the instance of tournament to the method. Which means, modify your main method to
public static void main(String[] args) throws Exception {
Tournament tournament = new Tournament();
performRegister(tournament);
}
public static void performRegister(Tournament tournament) {
tournament.register("e-LEMON-ators");
}
Now your test method becomes as below.
@Test
public void testTournament() {
try {
Tournament tournament = Mockito.mock(Tournament.class);
Mockito.when(tournament.isAlreadyRegistered(anyString())).thenReturn(true);
Tournament.performRegister(tournament);
} catch (Exception e) {
fail();
}
}
Edit :
Another solution is, If you don't want to modify Tournament
class, use PowerMock
.
Here is the test class
import static org.junit.Assert.fail;
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(Tournament.class)
public class TournamentTest {
@Test
public void testTournament() {
try {
Tournament mock = PowerMockito.mock(Tournament.class);
PowerMockito.when(mock.isAlreadyRegistered(anyString())).thenReturn(true);
PowerMockito.whenNew(Tournament.class).withAnyArguments().thenReturn(mock);
Tournament.main(null);
} catch (Exception e) {
fail();
}
}
}
Here are the dependencies
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
Here are the files for the reference
Tournament.java
: https://gist.github.com/sjabiulla/4bdf71f81079e38aef137e64913bf26b
TournamentTest.java
: https://gist.github.com/sjabiulla/4a557516e834bba6d6047687f7e32deb
pom.xml
: https://gist.github.com/sjabiulla/10abb153e82e14194fd1ccc2689b192d
Upvotes: 2