I am using SpringsourceTool and the Spring framework.
I have some code that uses JmsTemplate to send messages via convertAndSend(Object). I want to debug it as a JUnit test. So, for the test class, I select Run->Debug As->JUnit Test.
I set a breakpoint and was able to closely follow the trace until I hit jmsTemplate.convertAndSend(obj) in which case when I hit Step Into (F5), I get a
Source not found.
Edit Source Lookup Path
Thanks!
Firstly, your problem is to with how to use Eclipse, and attaching sources to your library dependencies. This isn't a problem with JmsTemplate or Spring.
Having said that, you don't need to unit test JmsTemplate - it's already been unit tested by the Spring team. You can assume it works.
If your code is coupled to JmsTemplate, then consider refactoring it to depend on the JmsOperations interface instead. You can then mock or stub out that interface in your test.
If a deeper introspection into your JMS-communication is needed:
add logging.level.com.ibm.mq=TRACE to your application.properties
add -Dcom.ibm.msg.client.commonservices.trace.status=ON to your java-startup-parameters
Then check
your application-logfile
the application-start-directory, where you sould find a *.TRC-file with a lot of debug-information
see: https://www.ibm.com/docs/en/ibm-mq/9.0?topic=tmcja-collecting-mq-classes-jms-trace-by-using-java-system-property
Related
I'm working on an integration with an older library so that it can use Spring Boot testing, and for that I need to register a certain bean very early in the process, so that an ApplicationListener<ApplicationReadyEvent> can add a PropertySource to the Environment.
This works fine in the normal startup, but when using the #SpringBootTest annotation I need to be able to inspect the TestContext very early and add it to the testing BootstrapContext, so that the application listener can access it also in the integration tests.
But I can't find a good way to add bean instances to the test BootstrapContext apart from specifying an initializer class in the spring.factories files, or am I missing something here?
I have been looking into using #BootstrapWith and subclassing SpringBootContextBootstrapper, but can't seem to find a way to add some kind of BootstrapregistryInitializer-like functions?
I'm trying to integrate Datadog into a Quarkus lambda function. The unit test is failing with a NullPointerException because Datadog can't get the function ARN from the context. It looks like there is a need to supply this header Lambda-Runtime-Invoked-Function-Arn in the HTTP request.
Is there anyway to customize the request headers using QuarkusTest? We are using LambdaClient.invoke.
Generally tests should be as close to the production run as possible, so altering headers does not seem to be the right path.
Is the unit test focused on the datadog part of the code?
If not:
If datadog just broke the existing unit tests, you have multiple options to fix it:
With #QuarkusTest you could just Mock the datadog related parts and register that instead of the original using #InjectMock.
I also found that using #QuarkusTest for unit testing can be a bit tricky in some cases and using plain Junit5 with Mockito can be a bit simpler with less unpredictable 'magic'.
If yes:
Since most things involving datadog is about sending data to an external service this might be more suitable for the scope of an integration test instead of a unit test. In that case you would need a test environment, or maybe reconsider if you really need to test external data collection at all.
I am trying to implement integration tests for my Tomcat application, but my issue is that the application is launched separately from the tests so the tests cannot access the application context and neither the database.
My idea is running the tests "within" the running application, so I can #Autowire EntityManager and check for instance the state of the database during testing or even create database entities for testing.
My only idea of doing this is to actually run the application programmatically from the tests as ClassPathXmlApplicationContext("applicationContext.xml") and the access the Context. This would work, but it would be very hard for debugging as we wouldn't be able to use Hotswapping during the testing. Also I guess the server would be stopped as soon as the tests would end. I guess that is not the best and correct solution.
EDIT:
My question was probably unclear, so I will try to clarify.
I have a Tomcat application with Spring and Hibernate. The Spring beans and Hibernate database connection is initialised when the Tomcat application is started. The issue is how to run the tests of the active Spring beans from methods annotated with #Test in src/test/java which are started separately.
Consider this class:
#Component
class MyRepository {
#Autowired
EntityManager em;
#Transactional
public void myMethod(MyEntity entity) {
// do some job with entity
...
em.flush();
}
}
This class will be initialised with Tomcat as a MyRepository bean.
To test it, I cannot just call new MyRepository().myMethod(...) - I need to access the bean. The issue is accessing the bean from the #Test method:
#Test
void testMyRepository() {
Item item = ...
// then use the repository to handle the entity
context.getBean(MyRepository.class).myMethod(item);
// then assert the state of the database
context.getBean(EntityManager.class).find(Item.class, ...) ...
}
I can probably get the context in the initialisation of the tests with
ApplicationContext context = ClassPathXmlApplicationContext("applicationContext.xml");
But it would mean launching the whole application each time the tests are started. The better solution would be if the application could run separately from the tests.
Hope my problem is more clear now.
I would suggest you to use the SpringRunner to start the Spring application context and perform your tests on that running instance. You can customize the context the way it doesn't contain parts you don't want to tests and you can create mocks for components that require some external resources (REST clients and such). Take a look at the Spring docs or Spring Boot docs.
If multiple tests use the same Spring context configuration, the context is started just once and reused. So it's good to have it's configuration in a parent class of your tests. You can autowire any Spring bean into your test and test it.
You can use an in-memory database (such as H2) instead of a production one, so your tests are not dependent on an external infrastructure. To initialize the database, use tools like Flyway or Liquibase. To clear the database before each test, you can use the #Sql annotation.
You can find many examples of projects with such tests, for example my own demo.
If you want to test an external system, I would suggest something like JMeter.
Unfortunately you cant mirror your classes and use them in your tests. Thats a big disadvantage of web services. They always depend on user / machine interaction. With a lot of effort you can extract the functionality of the essential classes or methods and construct test scenarios etc. with jUnit.
The Overview of your possibilities:
special drivers and placeholders
you can use a logger with detailed log-level and file output. Then you created scenarios with the expected result and compare it with your log files.
Capture replay tools. They record your exection and replay them for monitoring.
I can also recommend using Selenium for the frontend tests.
Hope it helped.
I have developed my application and I have a .properties file containing several key-value properties.
In my code I inject said properties like this:
#Value("${services.host}${services.name}")
private String hostname;
I am searching for a way to check every #Value inside of my code so to make sure that every property will be solved at runtime. Something like simulating my application startup.
Is it possible?
Yes, you can create a JUnit test class that loads your application context (just like your production code would) and then execute a test method that verifies that your property values have been injected.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {AppConfig.class})
public class SpringApplicationTest {
#Autowired
private MyServiceBean serviceBean;
#Test
public void shouldExecuteServiceBean_andProduceExpectedOutcome() {
//TODO test setup
serviceBean.doSomething()
//TODO assert output
}
}
In this example MyServiceBean.java is a class that would be executed from your Main class, so that you are testing the end-to-end logic of your application, including all of the spring dependency injections. Think of it as your "happy path" test scenario. I always include at least one test like this in my projects, to ensure that all of the spring injections are correct and load without error. You wan't to catch the errors before you build and deploy your code.
In the example above AppConfig.java is the same Spring configuration class you use when your code is deployed. You probably want to add another configuration class that overrides some properties/beans specifically for testing only.
#ContextConfiguration(classes = {AppConfig.class, TestConfig.class})
Using a test only class, you can mock out any dependencies that make testing difficult (i.e. use an in-memory database), and also override properties so you can test against "localhost" rather than another service which may or may not be available (so long as you can create an equivalent localhost service in your test setup).
Note: If you are finding it difficult to test your application due to too many dependencies, or external dependencies that cannot be swapped out easily, the pain you are feeling is a good guide to start thinking about how to change your architecture to support ease of testing. You also can just test portions of your application using the above concepts.
I'm writing a module-level integration test for a system using Spring Integration. I need the integration plan up and running but at this level am still using MockMvc and a mocked repository interface to ensure that I have all of my mappings, conversions, and message routing correct.
Right now, my module-level Enable configuration is meta-annotated with #EnableMongoRepositories, and the Spring test runner aborts because it doesn't have a live mongoTemplate to create the repositories from; the mock repository doesn't prevent the attempt to create real ones.
I know that I can conditionalize the inclusion of #EnableMongoRepositories, but is there simpler way to tell Spring Data not to create repository proxies if I'm already supplying mocks for them?
Basaically if I understand correctly you have two kinds of set up for your MongoDB repositories, mock and live. So you want to run integration tests and control the repository that is being used. I would suggest using "Spring Profiles".
create an simple interface say MongodbCofig
crate two configuration classes for mock and live. Make sure these classes implement MongodbConfig. Set the profiles (#Profiles) in both the classes.
Later activate the required profile before running the tests
For detailed understanding of profiles you can refer here