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);
}
}
Related
I have wrote an integration for testing a delete function like as shown below
#Test
void deleteUsersTest() {
Map<String, String> params = new HashMap<>();
params.put("id", "21");
this.template.delete("/v1/users/{id}", params);
:
}
The problem I am facing is, since it is a void function I would like to verify the below function is been called internally
userRepository.deleteById(21)
In Unit test I usually used something like this
verify(userRepository, times(1)).deleteById((long) 21);
but the above one is mockito based function which I cannot used in Integration test
Can someone help me on how to verify this function in Spring Integration test
I am using Spring 5, Spring Boot 2.1
Integration testing happens on a real database. Just ensure that the entity is stored in your database before calling delete and not stored in your database after calling delete.
#BeforeEach
public void setDatabase() {
client1 = new Client();
client1.setName("Karl");
client2 = new Client();
client2.setName("Pauline");
testEntityManager.persist(client1);
testEntityManager.persist(client2);
testEntityManager.flush();
}
#Test
public void deleteTest() {
clientRepository.deleteById(client1.getId());
List<Client> clientListActual = clientRepository.findAll();
boolean clientExists = clientListActual.contains(client1);
assertFalse(clientExists);
assertEquals(1, clientListActual.size());
}
I would recommend using #SpyBean, here is the example using spybean
Spy wraps the real bean but allows you to verify method invocation and mock individual methods without affecting any other method of the real bean. So, by making userRepository a SpyBean we can mock only the methods we want to mock in our test case and leave the others untouched.
Another way you can also use #MockBean to create a mock and use thenCallRealMethod() to call real method
#MockBean
private UserRepository userRepository
And then say call a real method
// Call a real method of a Mocked object
when(userRepository.deleteById(21l)).thenCallRealMethod();
So using the above statement it actually calls the real method, and now you can verify it
verify(userRepository, times(1)).deleteById(21l);
I am trying to unit test my Service classes that looks similiar to this:
#Service
public class SomeQueryService {
private final SomeRepository repository;
public SomeQueryService(SomeRepository repository) {
this.repository = repository;
}
public void doSomething() {
// code doing some magic
}
}
SomeRepository is simple repository interface extending JpaRepository interface.
What I want to do is unit test this service to verify whether it is working properly.
I do not want to use mockito to mock repository behaviour instead, I want to have some in-memory implementation (on list or map) that will imitate database behaviour.
Does Spring provide such fake implementations?
I want to avoid making Stub Implementation of such repository by myself as I will be using such tests in many other places.
RealLifeDeveloper has created an MIT-licensed helper-class to do just what you want: implement the repository-interface with a plain-old-java-object that just wraps a Collection, and called it "InMemoryJpaRepository". You will still have to implement some logic yourself1, though it should be easy if your queries are not too complicated.
An article explaining how to do this with example: https://reallifedeveloper.com/creating-in-memory-versions-of-spring-data-jpa-repositories-for-testing/
The repository (which includes other stuff, too) is on github: https://github.com/reallifedeveloper/rld-build-tool
The specific helper-files for creating the inmemory-db are found at https://github.com/reallifedeveloper/rld-build-tools/tree/master/src/main/java/com/reallifedeveloper/tools/test/database/inmemory if you dont want the whole repo.
1 The rule "Don't put logic in tests" exists for a reason and is clearly violated here. However, the well-known and widely-used alternatives mentioned by the other answers, H2-testing and extensive mocking, have their drawbacks too.
The type of testing you are referring to is called "Integration Testing" or "End to end testing" since it tests the whole application or a big chunk of it compared to unit tests that test only one method.
https://www.guru99.com/unit-test-vs-integration-test.html
You should not unit test your repositories, since they are already well tested by the spring team.
Solution:
You can create a test that starts the whole spring container using Spring Boot:
Just create a class in your test folder and annotate it with:
#RunWith(SpringRunner.class)
#SpringBootTest
public class MyTestClass {
#Test
public void test() {
}
}
You can then configure an embedded database using H2 so that your test does not use the production database, just follow the Spring Boot Database Initialization doc.
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
PS. You can also create a specific profile using the following annotation on your test class:
#ActiveProfiles("test")
No Spring Data does not provide a fake implementation of that interface.
You'll have to create it on your own or use a mocking framework like Mockito.
I'm new in Spring JMS, I'm trying to test a method that uses #JMSListener.
Do you have idea how to test this using mockrunner or other tool you know?
I've seen this sample but I'm not sure if this is applicable for my case.
https://dzone.com/articles/mockrunner-jms-spring-unit
#Service
public class MyJMSService {
#JmsListener(destination = "jms/queuename")
public void processMessage(ObjectMessage msg) throws JMSException {
//do stuff
}
}
I have not used mockrunner. But it should be similar to other mocking frameworks such as eazymock or mockito. What you need to do is mock all the external calls. In your test class inside the #BeforeMethod you can create and initialize the mocks. Then you record the mocks inside your test method, saying if this is called with these arguments, merely return this. Then you verify the mock interactions. Hope this helps. Happy coding.
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
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";
}
}
?