Springboot application is not autowiring all the instances so I manually wire all of them. Now JestClient mock is not getting set I only see the live object. Next actually I want to test if "aMethod is having jestclient.execute() then return jestResult"
#RunWith(SpringRunner.class)
#SpringBootTest(classes = IngestionApplicationTests.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#TestPropertySource(locations = "classpath:application-test.yml")
#ComponentScan(basePackages = { "com.package.accounts" })
public class IngestionApplicationTests {
#Autowired
private IngestionServiceImpl vaService;
#Autowired
private IngestionQueryUtil queryUtil;
#Mock
private JestClient client;
private JestResult result;
...
#Before
public void setUp() {
client = mock(JestClient.class);
String resultString="<jsonString>";
result.setJsonString(resultString);
result.setJsonObject(new JsonParser().parse(resultString).getAsJsonObject());
result.setSucceeded(true);
try {
when(client.execute(anyObject())).thenReturn(result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I see that Spring-Boot is creating a new context of its own and not running in test context.
Related
I want to call webservices via clients. The clients are instantiated as beans:
#Configuration
public class ServiceClientConfiguration {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(CONTEXT_PATH);
return marshaller;
}
#Bean
public Service1Client authenticate(Jaxb2Marshaller marshaller) {
Service1Client client = new Service1Client();
client.setDefaultUri("http://localhost:8292/service1");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
#Bean
public Service2Client broker(Jaxb2Marshaller marshaller) {
Service2Client client = new Service2Client();
client.setDefaultUri("http://localhost:8192/service2");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
Though the both of the services are different, the request and responses are defined via xsd-files to the same package name - which is provided here as String 'CONTEXT_PATH' to the marshaller.
The clients itself look like this:
public class Service1Client extends WebServiceGatewaySupport {
private static final Logger log = LoggerFactory.getLogger(Tools.getClassName());
public Service1Response process(Service1Request request) {
Service1Response response = null;
try {
response = (Service1Response) getWebServiceTemplate()
.marshalSendAndReceive("http://localhost:8292/service1", request);
} catch (Exception e) {
log.error("", e);
}
return response;
}
}
and
public class Service2Client extends WebServiceGatewaySupport {
private static final Logger log = LoggerFactory.getLogger(Tools.getClassName());
public Service2Response process(Service2Request request) {
Service2Response response = null;
try {
response = (Service2Response) getWebServiceTemplate()
.marshalSendAndReceive("http://localhost:8192/service2", request);
} catch (Exception e) {
log.error("", e);
}
return response;
}
}
While running Service1Client is fine, the Service2Client fails with
javax.xml.bind.JAXBException: class <package>.Service2Request nor any of its super class is known to this context.
I removed "Service1Client" from the code - but the error remained to be the same.
I have renamed the pathname of the CONTEXT_PATH. It was "types.". I changed it to "dto.". Now it works as expected.
For me the reason for the problem looks sort of strange - maybe somebody can explain it.
Spring Integration has ZooKeeper support as documented in https://docs.spring.io/spring-integration/reference/html/zookeeper.html
However this document is so vague.
It suggests adding below bean but does not give details on how to start/stop a poller when the node is granted leadership.
#Bean
public LeaderInitiatorFactoryBean leaderInitiator(CuratorFramework client) {
return new LeaderInitiatorFactoryBean()
.setClient(client)
.setPath("/siTest/")
.setRole("cluster");
}
Do we have any example on how to ensure below poller is run only once in a cluster at any time using zookeeper?
#Component
public class EventsPoller {
public void pullEvents() {
//pull events should be run by only one node in the cluster at any time
}
}
The LeaderInitiator emits an OnGrantedEvent and OnRevokedEvent, when it becomes leader and its leadership is revoked.
See https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#endpoint-roles and the next https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#leadership-event-handling for more info about those events handling and how it affects your components in the particular role.
Although I agree that Zookkeper chapter must have some link to that SmartLifecycleRoleController chapter. Feel free to raise a JIRA on the matter and contribution is welcome!
UPDATE
This is what I did in our test:
#RunWith(SpringRunner.class)
#DirtiesContext
public class LeaderInitiatorFactoryBeanTests extends ZookeeperTestSupport {
private static CuratorFramework client;
#Autowired
private PollableChannel stringsChannel;
#BeforeClass
public static void getClient() throws Exception {
client = createNewClient();
}
#AfterClass
public static void closeClient() {
if (client != null) {
client.close();
}
}
#Test
public void test() {
assertNotNull(this.stringsChannel.receive(10_000));
}
#Configuration
#EnableIntegration
public static class Config {
#Bean
public LeaderInitiatorFactoryBean leaderInitiator(CuratorFramework client) {
return new LeaderInitiatorFactoryBean()
.setClient(client)
.setPath("/siTest/")
.setRole("foo");
}
#Bean
public CuratorFramework client() {
return LeaderInitiatorFactoryBeanTests.client;
}
#Bean
#InboundChannelAdapter(channel = "stringsChannel", autoStartup = "false", poller = #Poller(fixedDelay = "100"))
#Role("foo")
public Supplier<String> inboundChannelAdapter() {
return () -> "foo";
}
#Bean
public PollableChannel stringsChannel() {
return new QueueChannel();
}
}
}
And I have in logs something like this:
2018-12-14 10:12:33,542 DEBUG [Curator-LeaderSelector-0] [org.springframework.integration.support.SmartLifecycleRoleController] - Starting [leaderInitiatorFactoryBeanTests.Config.inboundChannelAdapter.inboundChannelAdapter] in role foo
2018-12-14 10:12:33,578 DEBUG [Curator-LeaderSelector-0] [org.springframework.integration.support.SmartLifecycleRoleController] - Stopping [leaderInitiatorFactoryBeanTests.Config.inboundChannelAdapter.inboundChannelAdapter] in role foo
Android Studio 2.3
I have the following method I want to test inside my model class:
public class RecipeListModelImp implements RecipeListModelContract {
private Subscription subscription;
private RecipesAPI recipesAPI;
private RecipeSchedulers recipeSchedulers;
#Inject
public RecipeListModelImp(#NonNull RecipesAPI recipesAPI, #NonNull RecipeSchedulers recipeSchedulers) {
this.recipesAPI = Preconditions.checkNotNull(recipesAPI);
this.recipeSchedulers = Preconditions.checkNotNull(recipeSchedulers);
}
#Override
public void getRecipesFromAPI(final RecipeGetAllListener recipeGetAllListener) {
subscription = recipesAPI.getAllRecipes()
.subscribeOn(recipeSchedulers.getBackgroundScheduler())
.observeOn(recipeSchedulers.getUIScheduler())
.subscribe(new Subscriber<List<Recipe>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
recipeGetAllListener.onRecipeGetAllFailure(e.getMessage());
}
#Override
public void onNext(List<Recipe> recipe) {
recipeGetAllListener.onRecipeGetAllSuccess(recipe);
}
});
}
#Override
public void shutdown() {
if(subscription != null && !subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
Inside my test class I am testing like this:
public class RecipeListModelImpTest {
#Mock Subscription subscription;
#Mock RecipesAPI recipesAPI;
#Mock RecipeListModelContract.RecipeGetAllListener recipeGetAllListener;
#Mock List<Recipe> recipes;
#Inject RecipeSchedulers recipeSchedulers;
private RecipeListModelContract recipeListModel;
#Before
public void setup() {
TestBusbyComponent testBusbyComponent = DaggerTestBusbyComponent.builder()
.mockRecipeSchedulersModule(new MockRecipeSchedulersModule())
.build();
testBusbyComponent.inject(RecipeListModelImpTest.this);
MockitoAnnotations.initMocks(RecipeListModelImpTest.this);
recipeListModel = new RecipeListModelImp(recipesAPI, recipeSchedulers);
}
#Test(expected = NullPointerException.class)
public void testShouldThrowExceptionOnNullParameter() {
recipeListModel = new RecipeListModelImp(null, null);
}
#Test
public void testRecipeListModelShouldNotBeNull() {
assertNotNull(recipeListModel);
}
#Test
public void testShouldGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes()).thenReturn(Observable.just(recipes));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllSuccess(recipes);
verify(recipeGetAllListener, never()).onRecipeGetAllFailure(anyString());
}
#Test
public void testShouldFailToGetRecipesFromAPI() {
when(recipesAPI.getAllRecipes())
.thenReturn(Observable.<List<Recipe>>error(
new Throwable(new RuntimeException("Failed to get recipes"))));
recipeListModel.getRecipesFromAPI(recipeGetAllListener);
verify(recipesAPI, times(1)).getAllRecipes();
verify(recipeGetAllListener, times(1)).onRecipeGetAllFailure(anyString());
verify(recipeGetAllListener, never()).onRecipeGetAllSuccess(recipes);
}
#Test
public void testShouldShutdown() {
when(subscription.isUnsubscribed()).thenReturn(false);
final Field subscriptionField;
try {
subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscription);
} catch(NoSuchFieldException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
}
However, the problem is the Subscription in my model class is always null so will never enter the if blook. Is there any way to test this with using Mockito or spys?
Many thanks for any suggestions,
You should for testing recipeListModel class, where you have shutdown() method , set mock into this class.
If you don't have set method for subscription in recipeListModel , or constructor param.... ),you can set mock object with reflection like :
#Test
public void testShouldShutdown() {
Subscription subscription = mock(Subscription.class);
when(subscription.isUnsubscribed()).thenReturn(false);
Field subscriptionField = recipeListModel.getClass().getDeclaredField("subscription");
subscriptionField.setAccessible(true);
subscriptionField.set(recipeListModel, subscriptionMock);
recipeListModel.shutdown();
verify(subscription, times(1)).unsubscribe();
}
after your update :
if you can't change way of creation , you should mock it like (full way of creation) , i don't know your api , so it's just idea:
Subscription subscription = mock(Subscription.class);
when(subscription.isUnsubscribed()).thenReturn(false);
// preparation mock for create Subscription
//for recipesAPI.getAllRecipes()
Object mockFor_getAllRecipes = mock(....);
when(recipesAPI.getAllRecipes()).thenReturn(mockFor_getAllRecipes );
//for subscribeOn(recipeSchedulers.getBackgroundScheduler())
Object mockFor_subscribeOn = mock();
when(mockFor_getAllRecipes.subscribeOn(any())).thenReturn(mockFor_subscribeOn);
//for .observeOn(recipeSchedulers.getUIScheduler())
Object mockFor_observeOn = mock();
when(mockFor_subscribeOn .observeOn(any())).thenReturn(observeOn);
// for .subscribe
when(observeOn.subscribe(any()).thenReturn(subscription);
I used Spring 4.1.0 with Hibernate 4.3.6 and all is Ok.
After Spring migration to 4.2.8, the persistence does not work.
No exception, no trace the persist methode of entity manager is called but nothing in the database.
It's like if the transaction manager was not working.
this is my persistence configuration :
#Configuration
#EnableTransactionManagement
public class PersistenceConfiguration {
#Bean
public BasicDataSource driverManagerDataSource() {
final BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/xxx");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setValidationQuery("SELECT 1");
dataSource.setDefaultAutoCommit(false);
dataSource.setInitialSize(10);
dataSource.setMaxActive(20);
dataSource.setMaxIdle(10);
return dataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
final LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
localContainerEntityManagerFactoryBean.setDataSource(driverManagerDataSource());
localContainerEntityManagerFactoryBean.setPersistenceUnitName("xxxPersistenceUnitName");
localContainerEntityManagerFactoryBean.setPackagesToScan("org.xxx.model");
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(new org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter());
final HashMap<String, String> map = new HashMap<>();
map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
map.put("hibernate.hbm2ddl.auto", "update");
map.put("hibernate.show_sql", "false");
map.put("hibernate.format_sql", "false");
localContainerEntityManagerFactoryBean.setJpaPropertyMap(map);
localContainerEntityManagerFactoryBean.setJpaDialect(new org.springframework.orm.jpa.vendor.HibernateJpaDialect());
return localContainerEntityManagerFactoryBean;
}
#Bean
public JpaTransactionManager transactionManager() {
final JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(localContainerEntityManagerFactoryBean().getNativeEntityManagerFactory());
return jpaTransactionManager;
}
Dependence injection :
#Configuration
#Import({PersistenceConfiguration.class, UserConfiguration.class, SecurityConfiguration.class})
#ComponentScan(basePackages = "org.xxx")
#EnableWebMvc
public class XxxProjectConfiguration {
private static Logger LOG = Logger.getLogger(XxxProjectConfiguration.class);
#Autowired
private Environment env;
#PostConstruct
public void initApp() {
LOG.debug("Looking for Spring profiles...");
if (env.getActiveProfiles().length == 0) {
LOG.info("No Spring profile configured, running with default configuration.");
} else {
for (String profile : env.getActiveProfiles()) {
LOG.info("Detected Spring profile: {}" + profile);
}
}
}
#Autowired
private UserConfiguration userConfiguration;
// DAO
#Bean
public RelationshipDAO relationshipDAO() {
return new RelationshipDAOImpl();
}
#Bean
public RelationshipStatusDAO relationshipStatusDAO() {
return new RelationshipStatusDAOImpl();
}
#Bean
public MessageDAO messageDAO() {
return new MessageDAOImpl();
}
// Services
#Bean
public UserServiceImpl userService() {
return new UserServiceImpl(userConfiguration.userDAO(), relationshipDAO(), relationshipStatusDAO(), messageDAO());
}
}
And
#Configuration
#Import(PersistenceConfiguration.class)
public class UserConfiguration {
#Bean
public UserDAO userDAO() {
return new UserDAOImpl();
}
}
The service :
#Transactional(propagation=Propagation.SUPPORTS)
public class UserServiceImpl implements UserService, Serializable {
private static final long serialVersionUID = 1L;
private UserDAO userDAO;
private RelationshipDAO relationshipDAO;
private RelationshipStatusDAO relationshipStatusDAO;
private MessageDAO messageDAO;
public UserServiceImpl(final UserDAO userDAO, final RelationshipDAO relationshipDAO, final RelationshipStatusDAO relationshipStatusDAO, final MessageDAO messageDAO) {
this.userDAO = userDAO;
this.relationshipDAO = relationshipDAO;
this.relationshipStatusDAO = relationshipStatusDAO;
this.messageDAO = messageDAO;
}
#Override
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = UserServiceException.class)
public RelationshipStatus wantsRelationship(final long fromUserId, final long toUserId) throws UserServiceException {
try {
final Relationship relationship = new Relationship(new Date());
User fromUser = userDAO.get(fromUserId);
User toUser = new User(toUserId);
relationship.getUsers().add(fromUser);
fromUser.getRelationships().add(relationship);
relationship.getUsers().add(toUser);
toUser.getRelationships().add(relationship);
relationship.setWantsFromUserId(fromUserId);
final Message message = new Message(fromUserId, "Hi ! My name is " + fromUser.getFirstName() + ", I want to meet you");
relationship.getMessages().add(message);
relationship.setStatus(new RelationshipStatus(Status.WANTS));
relationshipDAO.persist(relationship);
return relationship.getStatus();
} catch (Exception e) {
throw new UserServiceException(e);
}
}
...
}
I do not understand anything...
The missing code is :
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
I'm looking to unit test my Java EE code by using the embedded Glassfish container and JUnit. On its own this works ok, but I've discovered that when the Primefaces EventBusFactory is called it fails with a Null Pointer Exception. I'm not sure how to resolve that, or if I should be testing this in another way.
Here is my test:
public class CreateOrderBookTest {
private RequestBean requestBean;
private EJBContainer ejbContainer;
private Context ctx;
#Before
public void setUp() throws Exception {
ejbContainer = EJBContainer.createEJBContainer();
System.out.println("Opening the container" );
ctx = ejbContainer.getContext();
}
#After
public void tearDown() throws Exception {
ejbContainer.close();
System.out.println("Closing the container" );
}
#Test
public void test() throws NamingException {
RequestBean requestBean = (RequestBean) ctx.lookup("java:global/classes/RequestBean");
assertNotNull(requestBean);
requestBean.createBidOrder(50, 1.0, "CLCS", "00001");
}
}
Here is the function I'm testing in a RequestScoped Stateful bean:
public void createBidOrder(Integer amount, Double price, String memberId, String traderId)
{
BidOrder order = new BidOrder(amount,price, em.find(Member.class, memberId),
em.find(Trader.class, new Integer(traderId)));
logger.log(Level.INFO, "RequestBean.createBidOrder Created new order with bidprice {0}",
new Object[]{price});
em.persist(order);
EventBus eventBus = EventBusFactory.getDefault().eventBus();
eventBus.publish("/notify", "order");
}