Create a JUnit for Camel route and processor - unit-testing

I am new to JUnit. I am trying to write test case for camel route and processor. I don't know how to start. Here is my route
from("activemq:queue1").process("queueprocessor").toD("activemq:queue2").
I need help to mock my endpoints and processor.

Here mocked all endpoints using "isMockEndpoints" & added expected body content to endpoint(activemq:queue2) and by sending same content as input to mocked endpoint(activemq: queue1) verified assert is satisfied or not.
public class MockEndpointsJUnit4Test extends CamelTestSupport {
#Override
public String isMockEndpoints() {
// override this method and return the pattern for which endpoints to mock.
// use * to indicate all
return "*";
}
#Test
public void testMockAllEndpoints() throws Exception {
// notice we have automatic mocked all endpoints and the name of the endpoints is "mock:uri"
getMockEndpoint("mock:activemq:queue2").expectedMessageCount(1);
getMockEndpoint("mock:activemq:queue2").expectedBodiesReceived("Hello World");
template.sendBody("mock:activemq:queue1", "Hello World");
getMockEndpoint("mock:activemq:queue2").assertIsSatisfied();
/* additional test to ensure correct endpoints in registry */
/* all the endpoints was mocked */
assertNotNull(context.hasEndpoint("mock:activemq:queue1"));
assertNotNull(context.hasEndpoint("mock:activemq:queue2"));
}
}

Related

PowerMock mock injected Authentication

i am using PowerMockRunner in a spring-boot application for testing. Everything is working but when my controllers actions definition contain someControllerMethod(..., Authentication auth, ...). Then auth is null and therefore some code is not working.
What i tried is to mock Authentication and SecurityContext. Came up with something like this
private void mockSecurity() {
Authentication authentication = mock(Authentication.class);
SecurityContext securityContext = mock(SecurityContext.class);
List<SimpleGrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("USER"));
User mockedUser = new User("testuser", "passwordtest", authorities);
when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
when(SecurityContextHolder.getContext().getAuthentication().getDetails()).thenReturn(mockedUser);
when(SecurityContextHolder.getContext().getAuthentication().getName()).thenReturn(mockedUser.getUsername());
}
Now those mocks work, if my code uses SecurityContextHolder.getContext().getAuthentication() method of accessing the authentication, but not for the one automatically injected (probably because it is not yet mocked when the controller mock is created).
Any ideas how to mock the injected Authentication so the code does not need to be changed? spring-security-testand #MockWithUser have the same result.
Relevant parts of the test look like this,
#RunWith(PowerMockRunner.class)
public class UserControllerTest {
#InjectMocks
UserController userController;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mockMvc = standaloneSetup(userController).build();
}
#Test
public void getUserDetails() {
mockSecurity();
mockMvc.perform(...).andExpect(...);
}
}
Edit as requested by pvpkiran the controller code
#RequestMapping(...)
public void getDetails(#PathVariable String id, Authentication auth) {
UserDetails loadedDetails = userService.getUserDetails(id);
if (!loadedDetails.getUserId().equals(auth.getName())) {
throw new Exception(...);
}
...
}

How to mock Response response = ClientBuilder.newClient().target(some url).request().post(Entity.entity(someEntity, MediaType.APPLICATION_JSON))?

I use Jersey client to post request and use Mockito to do unit test. The problem is I don't want to send a real request in the test. I try to mock the whole process like this
when(m_client.target(anyString())).thenReturn(m_webTarget);
when(m_webTarget.request()).thenReturn(m_builder);
when(m_builder.post(Entity.entity(m_Event, MediaType.APPLICATION_JSON))).thenReturn(m_response);
when(m_response.getStatus())
.thenReturn(Response.Status.BAD_REQUEST.getStatusCode());
But how to mock the ClientBuilder?
You can achieve this by using powermock.
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClientBuilder.class)
public class YourTestClass{
//create a mock client here
Client mockClient = Mockito.mock(Client.class);
// use powermockito to mock new call
#Before
public void setUp() throws Exception {
PowerMockito.mockStatic(ClientBuilder.class);
PowerMockito.when(ClientBuilder.newClient()).thenReturn(this.mockClient);
//Now you can use mockClient to mock any call using when... then..
}
#Test
public void yourTest() throws Exception {
}
}

How to write unit test for WEB API Http Method and Custom Route

I need to write unit test for, 1) web api method has [HTTPPOST] method type and 2) web api method has route attribute [api/Verification].
Can any one suggest, how to write test to do this.
I found one of the way for web api route verification using http://www.vannevel.net/2015/03/08/50/ but RouteAssert is not found.
I am writing unit test using MSTest.
Tried below way to find descriptor so, can check for route and httpmethods, problem is, its giving null for methodInfo.
private HttpActionDescriptor GetAction(AccountAPIController controller, string name)
{
try
{
MethodInfo methodInfo = controller.GetType().GetMethod(name, new Type[] { controller.GetType(), controller.GetType() });
return new ReflectedHttpActionDescriptor { MethodInfo = methodInfo, Configuration = controller.Configuration, ControllerDescriptor = new HttpControllerDescriptor()};
}
catch (Exception ex)
{
throw;
}
}
I found the solution by reflection to verify for class and method attributes. It works finally.
Thanks.

How do I unit test streaming download using jersey / dropwizard?

I have a resource method which produces a streaming download:
#GET
#Path("/{assetId}")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response download(#PathParam("assetId") String assetId) {
StreamingOutput stream = os -> service.download(assetId, os);
return Response.ok(stream).build();
}
I want to unit test this with a mock service object. I already have:
private static AssetsService service = Mockito.mock(AssetsService.class);
#ClassRule
public final static ResourceTestRule resource = ResourceTestRule.builder()
.addResource(new AssetsResource(service))
.addProvider(MultiPartFeature.class)
.build();
#Test
public void testDownload() {
reset(service);
// how to get an output stream from this?
resource.client().target("/assets/123").request().get();
}
Per my comment in the test, what do I need to do in order to get an outputstream from the response? I find the jersey client API pretty confusing.
Once I have this, I'll stub the service call so that it writes a known file, and test that it's received correctly.
Try this:
Response response = resource.client().target("/assets/123").request().get();
InputStream is = response.readEntity(InputStream.class);

How can I pass parameter from Apache CXF to Camel

I am working currently on project where Apache CXF is integrated with Apache Camel. Apache CXF is a solution that we use to expose a WebService then marshal/unmarshal SOAP request and pass it to Camel. This is pretty standard. By default a POJO dataFormat in ApacheCXF is used however there is a need for getting some information form SOAP headers "" and pass it to Camel. My question is how to do this? When I use Interceptor in Apache CXF I can get information that I need but I cannot pass it then to Camel. The class below is a CXF Interceptor
public class MyInterceptor extends AbstractSoapInterceptor {
//..... some variables
#Override
public void handleMessage(SoapMessage message) throws Fault {
//..some logic and then setting a variable
message.getExchange().put("Foo", "Bar");
}
}
... and class below is Camel Processor that is eventually called:
public class MyCamelProcessor implements Processor {
#Override
public void process(Exchange exchange) throws Exception {
//how can I read information from CXF Intercptor here?
//how can I read "Foo" value?
}
}
I understand that Exchange class that is used by Apache CXF is different then Exchange used by Camel however there should be a way of passing information between these two integrated technologies?
Finally, I solved it how follow:
In my context, I have a consumer service with camel-cxf component which is routed to Processor.
CxfEndpoint class from Camel has a method call setInInterceptors:
public void setInInterceptors(List<org.apache.cxf.interceptor.Interceptor<? extends org.apache.cxf.message.Message>> interceptors)
Therefore, if we define the next in our beans definitions file:
...
<cxf:cxfEndpoint id="consumerId"
address="/myservice"
serviceClass="com.example.service.MyServiceSEI">
<cxf:inInterceptors>
<ref bean="myInterceptor"/>
</cxf:inInterceptors>
</cxf:cxfEndpoint>
<bean id="myInterceptor" class="com.example.interceptors.MyInterceptor" />
Then, in our custom Interceptor we can set any variable in a map
...
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
...
public class MyInterceptor extends AbstractSoapInterceptor {
public MyInterceptor() {
super(Phase.RECEIVE);
}
#Override
public void handleMessage(SoapMessage message) throws Fault {
//..some logic and then setting a variable
message.getExchange().put("Foo", "Bar");
}
}
Finally, we can get the variables in our Processor, using org.apache.cxf.message.Message class, different from org.apache.camel.Message used with Exchange.getIn() method
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.cxf.message.Message;
import org.apache.camel.component.cxf.common.message.CxfConstants;
public class MyCamelProcessor implements Processor {
#Override
public void process(Exchange exchange) throws Exception {
//how can I read information from CXF Intercptor here?
//how can I read "Foo" value?
Message cxfMessage = exchange.getIn().getHeader(CxfConstants.CAMEL_CXF_MESSAGE, Message.class);
String foo = (String) cxfMessage.getExchange().get("Foo");
// read message from camel context
org.apache.camel.Message inMessage = exchange.getIn();
...
}
}
Thanks: http://camel.465427.n5.nabble.com/Getting-entire-Soap-Message-with-header-and-body-in-Payload-mode-td5753162.html