How to Mock Service class while writing a Junit for Spring-ws endpoint - junit

I have created a Spring SOAP based webservice which retrives data from my DB , I am able to test the service through SOAP UI , but now I am trying to add few functionalites for the service and I want to add some Junits for the service , Please find my Endpoint and Junit details below.
My End Point Class
#Endpoint
public class CountryEndPoint {
private static final String NAMESPACE_URI = "http://tutorialspoint/schemas";
#Autowired
CountryRepository countryRepository;
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
#ResponsePayload
public GetCountryResponse getCountry(#RequestPayload GetCountryRequest request) throws JDOMException {
Country country = countryRepository.findCountry(request.getName());
GetCountryResponse response = new GetCountryResponse();
response.setCountry(country);
return response;
}
}
Spring-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan
base-package="com.tutorialspoint" />
<sws:annotation-driven />
<bean id="schema"
class="org.springframework.core.io.ClassPathResource">
<constructor-arg index="0" value="*.xsd" />
</bean>
</beans>
Junit-Test calss
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "/spring-context.xml")
public class CustomerEndPointTest {
#Autowired
private ApplicationContext applicationContext;
#Autowired
private ResourceLoader resourceLoader;
private MockWebServiceClient mockClient;
private Resource schema = new ClassPathResource("countries.xsd");
#Before
public void createClient() {
mockClient = MockWebServiceClient.createClient(applicationContext);
GenericApplicationContext ctx = (GenericApplicationContext) applicationContext;
final XmlBeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(ctx);
definitionReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_NONE);
definitionReader.setNamespaceAware(true);
}
#Test
public void testCountryEndpoint() throws Exception {
Resource request = resourceLoader.getResource("request.xml");
Resource response = resourceLoader.getResource("response.xml");
mockClient.sendRequest(withPayload(request)).
andExpect(payload(response)).
andExpect(validPayload(schema));
}
}
I am able to run the test case with out any issue but my problem is I am not able to mock my service class (CountryRepository) mock the the code below.
Country country = countryRepository.findCountry(request.getName());
Does any one have any suggessions on this?

From your test case, I suppose your are trying to mock the CrudRepository object from inside a webservice call: That would be called integration testing. You need to make a choice for unit testing:
Test the request, and assert its response http status code (for example),
Or test the getCountry method inside your CountryEndPoint class. Doing both options at the same time would be considered an integration test.
I will try to answer considering the unit test case, using option 2. I think it will give you better insights for the future.
You are injecting the dependency of the CountryRepository on your CountryEndPoint class. You need to do the same on your testing class. For example, a basic setup would be:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "/spring-context.xml")
public class CustomerEndPointTest {
#InjectMocks
private CountryEndPoint countryEndPoint;
#Mock
private CountryRepository countryRepository;
#Test
public void testCountryEndpoint() throws Exception {
Mockito.when(countryRepository //...
countryEndPoint.getCountry(request //build a request object and pass it here.
//assertions...
}
}
Then, whenever a method from CountryRepository is invoked, it will be invoked from the mock instead. This is only possibly because of the injection of the mock via annotations.
If you actually send a request, using a HTTP client (like you intended), you cannot mock the methods being invoked inside your controller class, because you are not manipulating and assigning the instances yourself, and thus are not able to determine what is a mock, and what is not.

Related

request scoped beans in spring testing in Junit 5 Jupiter

My current spring boot testing uses junit5 jupiter. I need to add in request bean.
Following discussion request scoped beans in spring testing, https://github.com/mariuszs/spring-test-web I was able to get it working using JUnit4.
#RunWith(SpringJUnit4ClassRunner.class) //Not OK to remove
#SpringBootTest
#Testcontainers
#ActiveProfiles("test")
public class MainControllerTest {
#Autowired
MyRequestBean myRequestBean;
#Test
public void requestScope() throws Exception {
System.out.println("myRequestBean..." + myRequestBean.getRandom());
}
}
#Component
#RequestScope
#Data
public class MyRequestBean {
int random;
#PostConstruct
public void started() {
random = new Random().nextInt();
System.out.println("Request bean created! random = " + random);
}
}
But myRequestBean is null if I remove
#RunWith(SpringJUnit4ClassRunner.class) I can't keep it since it breaks my current testing using Jupiter
How to get request scope bean testing work in jupiter?
Updated:
I setup a testing project to test above. It might have issue on bring up SpringBootTest. Everything works after I tested in my real project. Spring 5 supports request-scope bean testing.

Unable to Mock functions inside static method Powermock

I am writing unit test for the below code using junit and mockito
public class Abc implements Runnable
{
private static ServerSocket server;
private static int port;
public Abc(int cPort)
{
port = cPort;
}
public void run()
{
init();
}
public static void init()
{
try {
server = new ServerSocket(port);
...something...
client.close();
}
}
catch(IOException e)
{
System.out.println("Exception inside init()...");
e.printStackTrace();
}
}
};
Unit test I have written
#RunWith(PowerMockRunner.class)
#PrepareForTest({ServerSocket.class})
public class abcTest {
#Mock (name = "server") //same name as private var.
ServerSocket mockServer;
#InjectMocks
Abc abc;
#Test
public void testInit() throws Exception {
int port = 1880;
Socket mockClient = Mockito.mock(Socket.class);
PowerMockito.whenNew(ServerSocket.class).
withArguments(anyInt()).thenReturn(mockServer);
abc = new Abc(port);
Abc.init();
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
};
But the call always go to original function definition. I am using junit 4.11 with mockito 2.28.2 and powermockito 2.0.2. I'm using java after a long time. Now its feel like kind of new. Please correct me if anything wrong in the code also.
You will need to change your PrepareForTest annotation
to #PrepareForTest({Abc.class}).
From the PowerMockito docu:
This annotation tells PowerMock to prepare certain classes for testing. Classes needed to be defined using this annotation are typically those that needs to be byte-code manipulated
In this case that refers to the class which creates the new instance of ServerSocket. ServerSocket itself is a non-final public class that does not require special handling from PowerMockito (instead Mockito can deal with this class on its own).
You could also change your test to do the following:
#Test
public void testInit() throws Exception {
int port = 1880;
ServerSocket mockServer = Mockito.mock(ServerSocket.class);
PowerMockito.whenNew(ServerSocket.class)
.withArguments(Mockito.anyInt()).thenReturn(mockServer);
Abc.port = port;
Abc.init();
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
(This first point is unrelated to whether the test fails or succeeds)
I do not know why you mix object's and static method behaviour together, but I think you should change that.In the test instead of creatic an ABC object, just could just set the static port variable directly.
Or alternatively change the whole ABC class into an object.
#InjectMocks failed for me as there is no default constructor
(Actually I got an error message in the console when trying to execute your code)
Additonaly you create a new instance of ABC in your test, which would have overwritten the things done by the annotations. Also as server is created during the init call, there is no need to inject a mock for it.
powermockito 2.0.2 actually depends on junit 4.12, so I am not sure what effects downgrading to an older version might have.
Socket mockClient seemed somewhat unrelated to the code your posted, so I removed it from my example in the answer, however as you use a client (I assume that is your Socket) in your code your probably need to do some mocking for that as well and provide the mock to the method accordingly.

Mocking test class Spring camel

I am new to camel. I am trying to write a test case.
public class A
{
private B b;
public void update(String s){
//calling some methods on B
.....
}
}
Test class
public class TestA extends CamelSpringTestSupport
{
private ClassPathXmlApplicationContext xmlAppContext;
#Test
public void testA()
{
String xml = "some xml";
Endpoint endpoint = context.getEndpoint("direct:incomingxml");
Exchange inExchange = endpoint.createExchange();
inExchange.getIn().setBody(xml);
inExchange.setPattern(ExchangePattern.InOnly);
template.send(endpoint, inExchange);
}
#Override
protected AbstractApplicationContext createApplicationContext()
{
xmlAppContext = new ClassPathXmlApplicationContext(
"classpath:/test-camel-context.xml");
return xmlAppContext;
}
}
spring bean xml
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:incomingxml"/>
<to uri="bean:classA?method=update"/>
</route>
</camelContext>
<bean id="b" class="B">
</bean>
<bean id="classA" class="A">
<constructor-arg index="0" ref="b" />
</bean>
There are couple of test cases pre-written using real objects. Is there any way I can mock this class B, gets injected in class A and mock few methods? I want to do in my test case only so that pre-written test cases remain unaffected?
You can solve this by adding a setter in you class A.
The application context will be loaded and A's B object will be injected by the bean declared in the XML but you can still override it with a mock of B by calling the newly defined setter in your test.
Then by doing that, B's mock will be used in your test and no the bean. The other test cases will not be affected.

Testing EJB 3.1 with JUnit gets error Invalid resource

I am trying to test an Stateless bean with JUnit in netbeans. This bean uses an EntityManager.
#Stateless
public class myEjb{
#PersistenceContext
private EntityManager em;
public MyResult getResult(){
return em.find(...);
}
}
Then I write a test class.
public class myTest{
private static EJBContainer ec;
private static Context ctx;
#BeforeClass
public static void setUpClass(){
ec = EJBContainer.createEJBContainer();
ctx = ec.getContext();
}
....
}
When I run the test, it does not work. I obtain the following message:
Invalid resource : mydb__pm
The error occurs when this line is executed:
ec = EJBContainer.createEJBContainer();
If a change my bean by removing the entity manager, it works. So, it seems that I have a problem with the entity manager.
My persistence.xml file is simple:
<persistence version="2.0" ...>
<persistence-unit name="MetisDemoPU" transaction-type="JTA">
<jta-data-source>MyDb</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
Finally, I create a JSF managed bean that called my EJB (which uses the entity manager) and it works.
#ManagedBean
#RequestScoped
public class myManagedBean{
#EJB
private OfferEjb offerEjb;
...
}
Any help would be appreciated!
Ok, I find a solution to my problem. I am now able to use JUnit to test my session bean with a persistence context.
I am not a specialist, so my explanation will probably not be complete.
With netbeans 7.2, there is an embedded glassfish server which is used for the test. It is necessary to configure the jdbc parameters in the domain.xml file and then for me it works.
On my computer, this file is under
C:\Program Files\glassfish-3.1.2.2\glassfish\domains\domain\
I just add a jdbc connection pool and a jdvc jndi.
This article contains more details.

Struts 2 json annotation

Ive been wanting to create a struts 2 with json return type using the annotation configuration. Ive successfully created this using the xml-type configuration like this snippet:
<action name="FetchJSON" class="com.stikiflem.Json" method="getJSON">
<result type="json"/>
</action>
I have posted a working demo of using an xml-type config here
http://stikiflem.wordpress.com/2008/08/27/struts-2-json-sample/
But how do I convert this to annotation? Here is my sample class:
public class JsonAction extends ActionSupport{
private List sampleList;
public String execute() {
sampleList = new ArrayList();
sampleList.add("stikiflem sample 1");
sampleList.add("stikiflem sample 2");
sampleList.add("stikiflem sample 3");
sampleList.add("stikiflem sample 4");
System.out.println("----------------------------------------------");
System.out.println("----------------------------------------------");
System.out.println("-sample111List:" + sampleList.toString());
System.out.println("----------------------------------------------");
System.out.println("----------------------------------------------");
return SUCCESS;
}
#Action(value="FetchJSON", results = {
#Result(name="success", type="json")
})
public String getJSON(){
System.out.println("get jason ko");
return execute();
}
public List getSampleList() {
return sampleList;
}
public void setSampleList(List sampleList) {
this.sampleList = sampleList;
}
}
Tried calling it by "json.action", it triggers the execute() method of course but cannot return a json type. Calling it by "FetchJSON" doesnt do anything. This question sounds stupid but there are just a small amount of tutorials and example of a detailed annotation in the net. Ive read a Manning Struts 2 in action book but it just barely scratch the surface, just the typical hello world and sucess,input redirection.
Ive searched the net high and low and so far, i havent seen any. I know there are a lot of programmers searching for this too.Hope someone can enlighten me about this one. Ive been banging my head on this for days already. :(
A similar question was asked here:
Struts2 JSON Plugin With Annotations
I got your action working by annotating it as follows:
#ParentPackage("json-default")
#Result(name="success", type="json")
public class JsonAction extends ActionSupport {
Get the JAR Dependencies
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.3.20</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.20</version>
</dependency>
Convention Plugin
The Convention Plugin is bundled with Struts since 2.1 and replaces the Codebehind Plugin and Zero Config plugins. It provides the following features :
Action location by package naming conventions
Result (JSP, FreeMarker, etc) location by naming conventions
Class name to URL naming convention
Package name to namespace convention
Action name overrides using annotations
Namespace overrides using annotations
XWork package overrides using annotations
Set Parent Package
Using annotation set the package as json-default to support the JSON.
#ParentPackage("json-default")
Set Result Type
#Result(name="success", type="json")
Define filter in web.xml
Define the struts 2 filter in web.xml and pass the action class by defining actionPackages.
Action Class
In this class data converted into JSON format.
#Result(name = "success", type = "json")
#ParentPackage("json-default")
public class StrutsJsonAnnotationAction extends ActionSupport {
private static final long serialVersionUID = 3516335522937177571L;
private String name = "Narendra Modi";
private String designation = "Prime Minister of India";
private String dob = "17 September 1950";
private String[] education = {"MA", "BA"};
private List<String> favBooks = new ArrayList<String>();
private Map<String, String> assumedOffice = new HashMap<String, String>();
public StrutsJsonAnnotationAction() {
favBooks.add("Ramayan");
favBooks.add("Geeta");
assumedOffice.put("President", "Pranab Mukherjee");
assumedOffice.put("Preceded by", "Manmohan Singh");
}
#org.apache.struts2.convention.annotation.Action("/india")
#Override
public String execute() {
return SUCCESS;
}
Source:
http://www.websparrow.org/struts/struts2-and-json-integration-using-annotation-example