JUnit test for #JmsListener - java

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.

Related

How to inject mock for only one test case with Quarkus/RestAssured

I'm attempting to test a REST controller (using Quarkus) endpoint using rest assured. I want to mock a class that is injected into that controller (ideally with Mockio), but only for one of my tests. Or get different behaviour per test case without having to have separate classes for each test. I'm not sure how to do this?
I've seen doing it the way from the documentation:
#Mock
#ApplicationScoped
public class MockExternalService extends ExternalService {
#Override
public String service() {
return "mock";
}
}
But this would only allow me to use one mock for all tests and not mock certain behaviours based on tests as I would with Mockito. I think?
I've tried creating a mock and annotating it with #Mock
#Mock
public TableExtractorService tableExtractorServiceMock = Mockito.mock(TableExtractorService.class);;
but I still get my real implementation when I use it. I'm using a constructor annotated with #Inject in my Controller that takes the TableExtractorService.
For a bit more information my test using restassured looks like this:
InputPart filePart = Mockito.mock(InputPart.class);
Mockito.when(tableExtractorServiceMock.Extract(anyObject()))
.thenThrow(IOException.class);
final InputStream inputStream = filePart.getBody(InputStream.class, null);
given()
.multiPart("file", inputStream)
.when().post("/document")
.then()
.statusCode(500);
That endpoint calls the service class that I'm trying to mock, and I want that mock to return an exception.
It can't be done. Quarkus documentation explains the issue:-
Although this mechanism is fairly straightforward to use, it nonetheless suffers from a few problems:
A new class (or a new CDI producer method) needs to be used for each bean type that requires a mock. In a large application where a lot of mocks are needed, the amount of boilerplate code increases unacceptably.
There is no way for a mock to be used for certain tests only. This is due to the fact that beans that are annotated with #Mock are normal CDI beans (and are therefore used throughout the application). Depending on what needs to be tested, this can be very problematic.
There is a no out of the box integration with Mockito, which is the de-facto standard for mocking in Java applications. Users can certainly use Mockito (most commonly by using a CDI producer method), but there is boilerplate code involved.
Link for reference: https://quarkus.io/blog/mocking/
According Quarkus test documentation, you can do it usingo #QuarkusMock or #InjectMock.
As #Ankush said, a class annotated with the #Mock annotation is using the CDI #Alternative mechanism, and will be global. #QuarkusTestProfiles can be used to define CDI #Alternatives for groups of tests.
For example, instead of annotating the mock with #Mock, it could be referenced in a test profile as
default Set<Class<?>> getEnabledAlternatives() {
return Set.of(MyMockThing.class);
}
Any test annotatated with the
#TestProfile(MyMockyTestProfile.class)
profile would get those mocks, while others would use the original implementation.
What may be a simpler method is to just use #InjectMock. For example, in the test class, declaring a field like this:
#InjectMock
MyThing mock;
will ensure that mock is used by the classes under test, just for this test.
For rest clients, it will also be necessary to add a #RestClient annotation, and if the original implementation is a singleton, convertscopes can be used to coax the scopes into something mockable.
#RestClient
#InjectMock(convertScopes = true)
MyThing mock;
Behaviour can be added to the injected mock in #BeforeEach or #BeforeAll methods. For example
#BeforeEach
public void setup() {
when(mock.someMethod()).thenReturn("some value");
}

Junit method invocation fails due to spring injection

I have written Junit test class to test particular method. One of the variables being processed in this method is spring injected, by taking the value from properties file.
Below is my test method
#Test
public void myTestMethod() {
//invoking the method to be tested
Assert.assertTrue(updateGroceries());
}
This is the class to be tested,
public class ToBeTested {
//Spring injected value
String categories;
public boolean updateGroceries() {
List<String> categoryList = StringUtils.convertStringToList(categories);
}
In the above class, categories variable is spring injected.
This is properties file content:
categories = Dals,Pulses,Dry Fruits,Edible Oil
Now while running my Junit method, execution is failing because dependency injection is failing.Since the code I want to test runs on tomcat. I want to test the code without running tomcat. Please suggest some solution.
First of all to run mockito you need to enable it over your test.
Using annotation #RunWith(MockitoJunitRunner.class) or execute at the beginning of your test Mockito.initMocks().
Then your test should look like:
#RunWith(MockitoJunitRunner.class)
private YourTest{
#InjectMocks
ToBeTested toBeTested;
#Mock
ToBeTestedDependency dependency;
#Before
public void setUp(){
ReflectionTestUtils.setField(toBeTested, "categories",
"someCategory");
}
#Test
public void shouldDoThisOrThat(){
toBeTested.updateCategories();
}
}
Unfortunately mockito doesn't support injecting #Valueannotated field. You need to use ReflectionTestUtils or setup run your test with SpringJUnit4ClassRunner where you need to define your spring context with PropertyPlaceholder configuration to resolve property that you have as your Value key. There you can find reference to documentation and example of spring testing approach.
Hope this helped.
You should look at Mockito. When you use mockito framework, you can create mocks for spring injected values. You should read more on mockito website.

Mocking aspects, testng and spring 4

I have a very basic scenario where I just need to call a method which has an annotation. This annotation simply calls an AspectJ advice. I just need to make sure that the advice is being called, ideally via a mock verify. Tests are being run using TestNG and mocking using Mockito. Spring is version 4.
class under test
public class MyClassUT
{
#MyAnnotation
public myMethod...
{
...
}
}
test class
#ContextConfiguration(classes = {SpringTestConfig.class})
#WebAppConfiguration
public class MyClassUtTest extends AbstractTestNGSpringContextTests
{
#InjectMocks private MyClassUT mine;
#BeforeMethod
public void init()
{
MockitoAnnotations.initMocks(this);
}
#Test
public void testMyMethod()
{
mine...
}
}
The problem is that the advice is being called and everything is OK, except for the fact that the advice class is instantiated once by spring and another time before calling the said method. The instance being used is the latter which of course has no dependencies injected so it fails. What I am trying to do is provide spring with a mock of my advice or at least inject a mock of the service it depends on and ask AspectJ to use that existing instance.
I have tried using factory methods for the advice, spring test configurations etc, however nothing seems to be working. I have tried also with EnableAspectJautoproxy to no avail, instantiated the aspect with a #Bean annotation, also as a factory method - but nothing works well unfortunately.
(It is also interesting to note that when I enable AspectJ in eclipse, the aspect test also run in maven and as far as I know, nothing changes in pom.xml.)
So, my question is:
How do I make the test use an instance of the aspect I or spring create so that when the method MyMethod is called, its dependencies are in place , or the mock version is used?
This problem is basically equivalent,
but
How do I do this without a single line of XML config - I've seen using an apectOf factory method config being mentioned a lot, but I need a pure annotation solution, if possible;
Works with TestNg not JUnit;
Thank you!

Arquillian + TestNG: How to access container managed objects in #Before/#After methods?

I couldn't find any satisfying solution for this problem, though other people have encountered it before...
I'd like to test a business bean which modifies persistent data using a dao.
The dao can be injected into the test methods as it is an ejb.
How to make it available in typical #Before/#After methods, for example to clean up the db.
Brief Example:
#PersistenceTest
public class MyTestClass extends Arquillian {
#Inject private Dao dao;
#Inject private MyBean myBean;
#BeforeMethod
public void cleanDB () {
dao.remove(foo); // Currently throws NPE as dao is not injected.
}
#Test
public void someTest () {
// In a Test-method dao is available and calling cleanDB from here also
// works as intended....
}
}
As far as I know only the Test-methods are executed in the container. Most information that I found seems to be outdated.
Is there any nice way to achieve this?
Thank you!
I'm using (managed) Wildfly 8 as app server.
Arquillan invokes the #Before** and #After** methods twice.
Once in client mode, once in container mode.
The only solution I found so far is, that you must verify that the dao was injected before you use it like :
#BeforeMethod
public void cleanDB () {
if (dao != null) {
dao.remove(foo);
}
}
So if you make a breakpoint and runs your code you should have 2 invokations of this method:
1st: dao is null
2nd: dao is injected
Hope that helps.
See also http://jayshaughnessy.blogspot.de/2012/11/arquillian-and-testng.html for more information.

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