package net.ttddyy.evernote.rest;
import com.evernote.clients.NoteStoreClient;
import com.evernote.clients.UserStoreClient;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.social.evernote.api.Evernote;
import org.springframework.social.evernote.api.NoteStoreOperations;
import org.springframework.social.evernote.api.StoreClientHolder;
import org.springframework.social.evernote.api.UserStoreOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
/**
* @author Tadaya Tsuyukubo
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(
classes = {Application.class, StoreOperationControllerUserStoreIntegrationTest.MockEvernoteConfig.class},
loader = SpringApplicationContextLoader.class,
initializers = IntegrationTestInitializer.class
)
public abstract class AbstractStoreOperationControllerIntegrationTest {
/**
* Configuration class to override a request scoped Evernote bean to a singleton bean to return a mock.
*/
@Configuration
public static class MockEvernoteConfig {
// currently evernote bean is only returning ~StoreOperations mocks.
// In future, if evernote bean gets tainted, need to change the scope to prototpye or reset the mock.
@Bean
public Evernote evernote() {
return mock(Evernote.class);
}
}
@Autowired
protected WebApplicationContext wac;
protected MockMvc mockMvc;
@Autowired
protected Evernote evernote;
@Autowired
protected ResourceLoader resourceLoader;
protected NoteStoreOperations noteStoreOperations;
protected UserStoreOperations userStoreOperations;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
// prepare mocks
this.noteStoreOperations = mock(NoteStoreOperations.class, withSettings().extraInterfaces(StoreClientHolder.class));
this.userStoreOperations = mock(UserStoreOperations.class, withSettings().extraInterfaces(StoreClientHolder.class));
// To work around getClass() method to return actual store-client class for parameter name discovery, use
// objenesis to create actual impl class instead of mocking.
// mockito cannot mock getClass() since this method is final.
Objenesis objenesis = new ObjenesisStd();
UserStoreClient userStoreClient = (UserStoreClient) objenesis.newInstance(UserStoreClient.class);
NoteStoreClient noteStoreClient = (NoteStoreClient) objenesis.newInstance(NoteStoreClient.class);
when(((StoreClientHolder) userStoreOperations).getStoreClient()).thenReturn(userStoreClient);
when(((StoreClientHolder) noteStoreOperations).getStoreClient()).thenReturn(noteStoreClient);
when(this.evernote.userStoreOperations()).thenReturn(userStoreOperations);
when(this.evernote.noteStoreOperations()).thenReturn(noteStoreOperations);
}
protected ResultActions performRequest(String url, String content) throws Exception {
return mockMvc.perform(post(url).content(content).contentType(MediaType.APPLICATION_JSON));
}
}