Unit testing a Play controller using mocks - junit

The title pretty much says it all. I would like to set up a traditional JUnit test to mock a controller's dependencies and run tests against actions.
I've found that I can achieve my goal like this:
public class AccountsControllerTest {
private controllers.Accounts accountsController;
#Test
public void test() {
running(fakeApplication(), new Runnable() {
public void run() {
accountsController = new controllers.Accounts();
accountsController.setAccountsWorkflow(mock(workflow.Accounts.class));
}
});
}
}
The obvious problem here is that I'm instantiating my class under test and injecting mock dependencies from the test method itself, when I should be doing that in the setup() method. It seems that the setup() method is useless if I'm going to test my controller in a traditional way.
Of course I can test controllers the way Play recommends, but my application is dependent on an external SOAP web service, so I need unit tests to show that our code is working when their servers are down.
So, what's the best way to unit test a Play controller using mocks while still taking advantage of setup() and teardown() methods?
Edit
I realize I'm assuming some knowledge here, so for those who are unaware, controller instantiation in a unit test must be wrapped in a running() function or Play! will throw a runtime exception saying that no application has been started.

You could accomplish this using Mockito and Play's FakeApplication and setting the static Http.Context variable.
This way you can write the test like all other JUnit test.
Example:
...
import static play.test.Helpers.status;
import play.test.FakeApplication;
import play.test.Helpers;
import play.mvc.Http;
import play.mvc.Result;
...
#RunWith(MockitoJUnitRunner.class)
public class ApplicationTest {
public static FakeApplication app;
#Mock
private Http.Request request;
#BeforeClass
public static void startApp() {
app = Helpers.fakeApplication();
Helpers.start(app);
}
#Before
public void setUp() throws Exception {
Map<String, String> flashData = Collections.emptyMap();
Http.Context context = new Http.Context(request, flashData, flashData);
Http.Context.current.set(context);
}
#Test
public void testIndex() {
final Result result = Application.index();
assertEquals(play.mvc.Http.Status.OK, status(result));
}
#AfterClass
public static void stopApp() {
Helpers.stop(app);
}

Related

How to verify an internal method call using Powermock?

I am trying to use PowerMockito to test a save method by verifying an internal audit() method call.
This internal call is made by auditor object which is being instantiated in an init() method of the class. As it is not injected I will not be able to mock it directly. When I used Mockito to verify it always said "There were zero interaction with the mock".
Question:How exactly do I test the save feature? Kindly help!
public class DaoImpl implements Dao{
private Auditor auditor;
#InjectValue
private ObjectLoader loader;
#InjectValue
private ConfigurationProvider confProvider;
#PostConstruct
public void init() {
//Mock this object instantiation and verify audit is called once
auditor = new SyncAuditor(confProvider.getClientConfiguration(), new EventRegProvider());
}
#Override
public void save(final AuditEvt auditEvt) {
final AuditedEvent auditedEvent = builder.build();
auditor.audit(auditedEvent);
}
Test :
#RunWith(PowerMockRunner.class)
#PrepareForTest({ DaoImplTest.class })
#PowerMockIgnore("javax.management.*")
public class DaoImplTest extends PowerMockito {
#InjectMocks
private DaoImpl dataAccess;
#Mock
private SynchAuditor auditorMock;
#Before
public void setUp() throws Exception {
loader = ObjectLoader.init("JUNIT");
loader.bind(ConfigurationProvider.class, configurationProviderMock);
dataAccess = loader.newInstance(DaoImpl.class);
}
#After
public void tearDown() {
loader.release(dataAccess);
ConnectionMgr.disconnect("JUNIT");
}
#Test
public void testSaveAuditEvent() throws Exception {
PowerMockito.whenNew(SynchAuditor.class).
withArguments(Matchers.any(ClientConfiguration.class), Matchers.any(EventRegProvider.class)).thenReturn(this.auditorMock);
final AuditEvent event = AuditEvent.from(null, "principal", UUID.randomUUID().toString(), "randomText",
new AuditEvtDefn((long) 522, "234242", "234242fdgd", true), SUCCESS, null, new GregorianCalendar());
dataAccess.save(event);
Mockito.verify(auditorMock, times(1)).audit(Matchers.any(AuditedEvent.class));
}
Even PowerMockito.verifyNew says there were zero interaction
PowerMockito.verifyNew(SynchronousAuditor.class,times(1)).withArguments(Matchers.any(AuditorClientConfiguration.class),Matchers.any(EventRegistrationProvider.class));
So, I figured out that java reflection will help in such a situation. You will have to get hold onto the real object and then set mocked object to it.
final Field privateAuditorField = DaoImpl.class.getDeclaredField("auditor");
privateAuditorField.setAccessible(true);
privateAuditorField.set(dataAccess, auditorMock);
Now verify will run sucessfully.
Mockito.verify(auditorMock, Mockito.times(1)).audit(Matchers.any(AuditedEvent.class));

Unit testing spring mvc with spring-test and junit

I am new to unit testing with spring-test. I have a spring-mvc-rest application. I am able to mock the environment using MockMvc.
My question is do I need to build the MockMvc object in every class of testing?
Would that not be repetitive configuration.
Is there a way to define this in one class and use it across every testing class?
If we go by single configuration or multiple configuration then which is the best way (by design and by maintenance)?
It's called inhertance
for example
Base Class
#ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
public class BaseTest
{
protected MockMvc mockMvc;
#Before
public void setup()
{
mockMvc = MockMvcBuilders.standaloneSetup().build();
}
}
Extend
public class ExtendedTest extends BaseTest
{
#Test
public void test()
{
//execute test here we have access to the mockMVC
}
}

How to have individual SetUp functions in Junit

I have two test functions and for each I want to have different #Before methods. How to achieve this ?
Although it seems to be convenient to organize all the test under the same class, for your case I think the best option is to separate the tests into different classes, each one with his corresponding setUp.
An alternative (I prefer the previous option) could be call the setUp directly in your test method, like the example as follows:
public class FooTest {
public void setUpMethod1() {
// do setUp things
}
public void setUpMethod2() {
// do setUp things
}
#Test
public void testMethod1() {
setUpMethod1();
// Test
}
#Test
public void testMethod2() {
setUpMethod2();
// Test
}
}
Only as a curiosity (IMO not recomended for your case), you can override the default junit RunListener with your own implementation. Method testStarted is executed before every test and you have access to class and methodName to be able to identify the running test. Dummy sample:
public class MyRunListener extends RunListener {
#Override
public void testStarted(Description description) throws Exception {
//...
Class testClass = description.getClass();
String methodName = description.getMethodName();
//...
}
}
Hope it helps.

how do I use powermockito verifyNew?

Having trouble with this. I've used Powermockito quite a bit in the past. Normally this is pretty smooth. I figured I'd post my problem rather than continue to rummage through examples. So the goal is to verify a call to new for a class. I don't think this is the most popular feature of powermockito.
Here's the test:
import static org.powermock.api.mockito.PowerMockito.verifyNew;
import static org.powermock.api.mockito.PowerMockito.whenNew;
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassUnderTest.class)
public class VerifyNewTest {
ClassUnderTest myClassUnderTest = new ClassUnderTest();
#Before
public void setUp() throws Exception {
}
#Test
public void test() throws Exception {
whenNew(Collaborator.class).withNoArguments().thenReturn(new Collaborator());
myClassUnderTest.doSomething();
verifyNew(Collaborator.class).withNoArguments();
}
}
and said classes
public class ClassUnderTest {
public void doSomething() {
new Collaborator();
}
}
public class Collaborator {
}
My goal was to make this as simple as possible. I suppose I could have added some mock objects and stubbed some behavior. Anyway, I get.
org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.invocationcontrol. MockitoNewInvocationControl.expectSubstitutionLogic(MockitoNewInvocationControl.java:65)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
Return a mock object in the whenNew() clause would work in your case.
#Test
public void test() throws Exception {
whenNew(Collaborator.class).withNoArguments().thenReturn(mock(Collaborator.class));
myClassUnderTest.doSomething();
verifyNew(Collaborator.class).withNoArguments();
}

Mocking a class in PowerMock

I am using PowerMocking for JUNIT and Iam new to PowerMock.
I want to mock one class which is non static.
The class scenario goes as follows.
public class Export extends MyUtil implements ExportFormatting<DeptSummaryByDCDTO, LmReportsInputDTO>{
public String createPDF(List<DeptSummaryByDCDTO> summaryDtoList, LmReportsInputDTO inputDto){
}
public String createPDF(Map<String, DeptSummaryByDCDTO> paramMap,
LmReportsInputDTO paramK) {
}
}
The calling class is as follows.
public static Response getMultiplePackSku{
filePath = new Export(inputDto).createPDF(resultList,null);
}
The Question is,
I am trying to test the above class using powermock.
Can anybody tell how to mock the line filePath.....
You need to first mock the constructor and return an Export mock. On the returned mock you need to record the call to createPDF. The tricky part is the constructor mocking. I'll give you an example, hopefully you'll get all of it:
#RunWith(PowerMockRunner.class) // This annotation is for using PowerMock
#PrepareForTest(Export.class) // This annotation is for mocking the Export constructor
public class MyTests {
private mockExport;
#Before
public void setUp () {
// Create the mock
mockExport = PowerMock.createMock(Export.class)
}
#Test
public void testWithConstructor() {
SomeDtoClass inputDto = PowerMock.createMock(SomeDtoClass.class);
PowerMock.expectNew(Export.class, inputDto).andReturn(mockExport);
PowerMock.replay(mockExport, Export.class);
expect(mockExport.createPDF(resultList, null);
// Run the tested method.
}
}
Here is a description of how to mock a constructor call: MockConstructor