Mock web service using mocking framework without using junit - java

This is my web service
#Path("/base")
public class ServiceMappingBusinessLogic1 {
#Mock Buiness1Service mockbusinesss1service;
#GET
public Response getService( String id) {
when(mockbusinessservice.getService("id")).thenReturn("mockservice");
String service = mockbusinessservice.getService();
return Response.status(200).entity(service).build();
}
This is serviceInterface
public interface Buiness1Service {
String getService(String id);
}
Buiness1Service is not implemented yet so,i am trying to use mock service
I am using SOAP UI to Test service .I am using jersey.
I am trying to use Mockito as mock service provider.But,from the testing i have confirmed that mockito does not mock alone it need unit testing framework like junit to work together.
I am unable mock service only using mockito.
So,my question is how to mock service without including junit in web service layer .In my case i need to mock Buiness1Service service ,but i am unable do that.Any good idea ?Please help

why cant you provide Buiness1Service class like
public class Buiness1ServiceImpl implements Buiness1Service{
public String getService(String id){
return "mockservice";
}
}
?

Related

My rest services relies on an external service. How do I mock it to use on my cucumber tests?

I made some cucumber tests (given, when, then integration tests) in spring boot maven, and I was able to test my endpoints using TestRestTemplate, but only if the external service is running.
The external service job is to check some fields before I save the information to the database.
When running the application normally the external service is called by FeignClient.
Is it possible to mock the external service while using TestRestTemplate to test the endpoints?
EDIT:
Sample mockup of the structure
Controller.java
#Autowired
EmployeeSvc employeeSvc;
#PostMapping(/save)
public ResponseEntity<String> saveEmployee(#RequestBody EmployeeDTO employeeDTO) {
employeeSvc.save(employeeDTO);
}
EmployeeSvc.java
#Autowired
ExternalSvcClient externalSvcClient; //External service is called by feignclient here.
#Autowired
EmployeeRepository employeeRepository;
public void save(EmployeeDTO employeeDTO) {
externalSvcClient.check(employeeDTO);
...some other code
Employee employee = dtoTransformer.transoform(employeeDTO);
employeeRepository.save(employee);
}
OK I managed to make my tests using wiremock by following this .
For stubs be sure not to include the parameters in the path:
if your request url looks like this
myrequest/?value1=someValue
make it like this in the stubs and append the parameters on the rest template or else it won't work
myrequest/
restTemplate.getForEntity(url+"value1=someValue"....)

Java integration test with fake outbound call

I work on a Java project using Spring framework, JUnit and Mockito.
The application is in the middle of a chain with others application, so it exposes inbound ports (e.g. an HTTP API) to be called and uses outbound ports (e.g. web services and database) to call other apps.
I want to write something like an integration test that should pass through the whole java code from the inbound port to the outbound port, but without doing any call to anything that's outside of the project.
Let's take a very-simple-but-very-concrete example :
We expose an HTTP endpoint to get customers and we call another app to get them.
In the domain : customers are represented by the Customer class.
In the externalapp layer : customers are represented by the CustomerModel class.
In the rest layer : customers are represented by the CustomerDto class.
Thus :
The CustomerSupplierAdapter class gets data from CustomerRepository and does the mapping from CustomerModel to Customer.
The CustomerControllerAdapter class does the mapping from Customer to CustomerDto and returns the data.
Now, I want to test my app by calling the CustomerControllerAdapter's getCustomers(), which will call the real service, which will call the real supplier, which will call a fake repository.
I wrote the following code :
#ExtendWith(SpringExtension.class)
class CustomerIntegrationTest {
#Mock
private CustomerRepository repository;
#InjectMocks
private CustomerControllerAdapter controller;
#BeforeAll
void setupAll() {
CustomerOutboundPort customerOutboundPort = new CustomerSupplierAdapter(repository);
CustomerInboundPort customerInboundPort = new CustomerService(customerOutboundPort);
controller = new CustomerControllerAdapter(customerInboundPort);
}
#Test
void bulkQuery() {
// Given
CustomerModel model = new CustomerModel();
model.setName("Arya Stark");
doReturn(List.of(model)).when(repository).getCustomers();
// When
List<CustomerDto> dtos = controller.getCustomers();
// Then
assertThat(dtos).hasSize(1);
assertThat(dtos.get(0).getName()).isEqualTo("Arya Stark");
}
}
But in this code, I do the "constructor's wiring" by myself in the setupAll() instead of relying on Spring dependency injection. It is not a viable solution because it would be very hard to maintain in real-life context (controller may have multiple services, service may have multiple suppliers, etc).
Actually, I would like to have something like an annotation to set on a CustomerRepository instance to programmatically overload dependency injection. Like : "Hey Spring, if any #Service class needs a CustomerRepository then you should use this fake one instead of the usual concrete implementation" without having to do the wiring by myself.
Is there any way to achieve that using Spring, JUnit, Mockito or anything else ?
If you really want to replace every CustomerRepository in your tests (everywhere!) with a mock, I'd recommend going for a configuration which provides a #Bean, which creates a mocked bean.
#Profile("test")
#Configuration
public class TestConfiguration {
#Bean
#Primary
public CustomerRepository customerRepostiory() {
return Mockito.mock(CustomerRepository.class);
}
}
#MockBean can have negative effects on your test duration as it's quite possible Spring needs to restart it's context.
Alternatively, I'd recommend NOT mocking your repository at all, but instead using either an in memory equivalent (H2) or the TestContainers framework to start the real database for you. Instead of mocking, you insert data into your repository before you start your tests.

Functional tests with Jersey Test, Grizzly and HK2 Dependency Injection

I'm attempting to write functional tests for my REST API using the Jersey Test framework. However, I've seem to hit a roadblock when it comes to using dependency injection within my functional tests. My main application looks like this:
#ApplicationPath("/")
public class Application extends ResourceConfig {
private static final URI BASE_URI = URI.create("http://localhost:8080/api/");
public static void main(String[] args) throws Exception {
System.out.println("Starting application...");
final ServiceLocator locator = ServiceLocatorUtilities.createAndPopulateServiceLocator();
final ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(JacksonFeature.class);
resourceConfig.register(LoggingFeature.class);
resourceConfig.packages(true, "my.package.name");
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, locator);
Runtime.getRuntime().addShutdownHook(new Thread(server::shutdownNow));
server.start();
Thread.currentThread().join();
}
}
Notice here that I'm using the HK2's ServiceLocatorUtilities.createAndPopulateServiceLocator() method in order to read the hk2-metadata-generator file. This method creates a ServiceLocator object which then in turn is passed to the GrizzlyHttpServerFactory.createHttpServer method. This all works great for running the Grizzly server, however, the question I have now is how do I create functional tests for my application with the Jersey Test Framework?
My unit test currently looks like this:
public class FormsResourceTest extends JerseyTest {
#Override
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
return new GrizzlyWebTestContainerFactory();
}
#Test
public void testMe() {
Response response = target("/test").request().get();
assertEquals("Should return status 200", 200, response.getStatus());
}
}
Is there even a way to use the HK2 service locator with the Jersey Test framework or do I need to treat my application as an external container and use the external container provider as documented here: External container?
Also, since these are functional tests, mocking the injected services is not an option here.
You can use the Locator Bridge to take two separate locator (the one you created and the one from Jersey) and bridge them together. The bridge can be made bi-directional as well (within limits) and so it'll appear in most normal usage to be one large ServiceLocator.
Note that there was a bug fixed this week with the ServiceLocator bridge which has not yet been pushed out to maven but will (probably) be pushed sometime next week. See HK2-295

How to mock an Authenticator in play framework with guice injections?

I have a play application with authenticated routes. I implemented an Authenticator, storing users into elasticsearch. My securized methods in my controllers are annotated with the #Security.Authenticated annotation. For my unit tests with mockito, I would like to mock this class but I don't know how to do this.
I am using DI with Guice. So I tried this approach:
Develop an AuthenticatorWrapper as following:
public class AuthenticatorWrapper extends Security.Authenticator {
private Authenticator authenticator;
#Override
public String getUsername(Http.Context ctx) {
return authenticator.getUsername(ctx);
}
#Override
public Result onUnauthorized(Http.Context ctx) {
return authenticator.onUnauthorized(ctx);
}
#Inject
public void setAuthenticator(Authenticator authenticator) {
this.authenticator = authenticator;
}
}
This class has an Authenticator as parameter, which is supposed to be injected by Guice when the app starts.
I developed a guice module defining a binding for class Authenticator.class to MyCustomAuthenticator.class
My securized route are annotated with #Security.Authenticated(AuthenticatorWrapper.class)
In my test I can easily provide a mock of class MyCustomAuthenticator my creating the mock, define test scope guice module, and defining a binding from Authenticator.class to my mock.
I thought this should work but this is not the case. Both at normal runtime or from my tests, the binding seems not working. I have nullPointerException from the wrapper when: the Authenticator parameter is not injected by Guice.
So my questions are:
Does the Authenticator is a good approach to Inject my authenticator from Guice? Maybe there is an easier way to inject a play Authenticator into annotations from Guice?
Is it normal that Authenticator is not injected by Guice into my wrapper? [EDIT -> yes because the annotation manually instantiates my object and doesn't use guice. Am I right?]
I can simplify my application by set directly MyCustomAuthenticator into the annotations, but how can I mock this authenticator in my tests?
Thanks :)
A found a workaround. I just used an access method provided by Play framework 2.4 since it fully integrates Guice. Here is my Authentication Wrapper class:
public class AuthenticatorWrapper extends Security.Authenticator {
private final Security.Authenticator authenticator;
public AuthenticatorWrapper() {
authenticator = Play.application().injector().instanceOf(Security.Authenticator.class);
}
#Override
public String getUsername(Http.Context ctx) {
return authenticator.getUsername(ctx);
}
#Override
public Result onUnauthorized(Http.Context ctx) {
return authenticator.onUnauthorized(ctx);
}
}
I just use the Play.application().injector() accessor to get a Security.Authenticator instance provided by Guice. So in my application.conf, I just configure a Guice Module which binds Security.Authenticator to the wanted implementation.

How to test remote android aidl service

I have a small app that interacts with a remote android service. I would like to mock that service in unit tests. I use Robolectric and JUnit for other test cases and shadows but I could not figure how to deal with remote services.
Is it sufficient to create and start a test service using the same package with the real service and export methods using same aidl?
Since I don't have the code for that service, I assume that I can not use Robolectric's ShadowService which requires actual class to be there.
Thanks a lot.
I would use Mockito to create a Mock of the interface and then pass that instance to your code in your tests. You could also manually create an implementation of that interface in your test code and use that.
So you have to do the mocking yourself and it is important that the code you want to tests uses some form of dependency injection to aquire a reference to the aidl interface, so you can pass your own mock in your tests.
If you want to write a unit test for service then you can use Mockito for mocking service behavior.If you want to test your service on the real device then this is how you can connect with your service.
#RunWith(AndroidJUnit4.class)
public classRemoteProductServiceTest {
#Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
#Test
public void testWithStartedService() throws TimeoutException {
mServiceRule.startService(
new Intent(InstrumentationRegistry.getTargetContext(), ProductService.class));
//do something
}
#Test
public void testWithBoundService() throws TimeoutException, RemoteException {
IBinder binder = mServiceRule.bindService(
new Intent(InstrumentationRegistry.getTargetContext(), ProductService.class));
IRemoteProductService iRemoteProductService = IRemoteProductService.Stub.asInterface(binder);
assertNotNull(iRemoteProductService);
iRemoteProductService.addProduct("tanvi", 12, 12.2f);
assertEquals(iRemoteProductService.getProduct("tanvi").getQuantity(), 12);
}
}

Categories

Resources