I am trying to run main application test class. But it's always gives Failed to Load Application context
Application.java
#SpringBootApplication
#ComponentScan(basePackages = { "com.aaa.abc","com.aaa.def" })
public class Application extends SpringBootServletInitilizer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
protected SpringApplicationBuilder configure (SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
ApplicationTest.java
#SpringBootTest
class ApplicationTest {
#Test
void contextLoads() {
}
}
I tied by providing path of Application class in ApplicationTest class as specified below. But it's giving same exception
#SpringBootTest(classes={com.aaa.Application.class})
Related
In the test class trying to test the main method and not sure how to use the mock object here.
How to use the mock object orders to call the main method and it's methods inside the main method
Any suggestions on how this can be done?
public class Orders {
public static void main(String[] s) {
Orders jp = new Orders();
jp.method1();
List<OrderItems> lstOrdItms = jp.getListOrderItems();
jp.processOrderItems( lstOrdItms );
}
public void method1(List<OrderItem> lstOrderItem) {
.........
}
public List<OrderItem> getListOrderItems() {
............
}
public void processOrderItems() {
............
}
}
public class OrdersTest {
#Mocks
Orders orders;
.....
#Before
public void setUp() {
........
}
#Test
public void testMain() throws SQLException {
// Not sure how to test here
// This will actually execute the main method instead of mock.
orders.main(new String[]{});
}
}
Normally, when I use #SpringBootTest I get the full context of beans. I can the #Autowire all kinds of beans that are available after the application has started.
Now, in the scope of spring-integration-test libary, the #SpringIntegrationTest does not do this.
As the testing module promises, you can use
#Autowired
private MockIntegrationContext mockIntegrationContext;
However, after inspecting the bean map on that instance, I found out there are no beans!
Example test:
#ActiveProfiles("test")
#RunWith(SpringRunner.class)
#SpringIntegrationTest
public class AppTest {
#Autowired
private MockIntegrationContext mockIntegrationContext;
#Test
public void contextLoads() {
// put breakpoint to inspect field
System.out.println(mockIntegrationContext);
}
}
When I however run the following code, I get a complete context:
#ActiveProfiles("test")
#RunWith(SpringRunner.class)
#SpringBootTest
public class App2Test {
#Autowired
private ListableBeanFactory beanFactory;
#Test
public void contextLoads() {
Assert.isTrue(beanFactory.getBeanDefinitionCount() > 0)
}
}
Why is that? How can I achieve a similar result with spring-integration-test?
Reading materials: https://docs.spring.io/spring-integration/docs/current/reference/html/testing.html
They are independent annotations; you need both.
EDIT
This works fine for me:
#RunWith(SpringRunner.class)
#SpringBootTest
#SpringIntegrationTest
public class So52297757ApplicationTests {
#Autowired
private MockIntegrationContext mockIntegrationContext;
#Autowired
private String foo;
#Test
public void contextLoads() {
System.out.println(foo);
System.out.println(mockIntegrationContext);
}
}
and
#SpringBootApplication
public class So52297757Application {
public static void main(String[] args) {
SpringApplication.run(So52297757Application.class, args);
}
#Bean
public String foo() {
return "foo";
}
}
and
foo
org.springframework.integration.test.context.MockIntegrationContext#1de5f0ef
Is it possible to have an instance of Clock being configured per test class?
Problem is that Clock of the current test is being overwritten by the configuration of another test.
I'm configuring my tests like bellow:
public class ClockTestCase extends AbstractTestCase {
#Configuration
static class ContextConfiguration {
#Bean
#Primary
Clock fixedClock() {
LocalDateTime fixed = ...
return Clock.fixed(fixed.toInstant(ZoneOffset.of(AMERICA_SAO_PAULO_OFFSET_ID)), ZoneId.systemDefault());
}
}
#Test
public void test() throws Exception {
// Act and Assert
this.mvc()
.perform(put(MY_URL, 1))
.andDo(print())
.andExpect(status().isNotFound());
}
}
In guice, Is there a way to select particular implementation for binding based on some external parameter
Eg:
public interface Service {
void sendMessage()
}
class EmailService implements Service {
public EmailService() { }
#Override
void sendMessage() {
println "Sending email..."
}
}
class SMSService implements Service {
public EmailService() { }
#Override
void sendMessage() {
println "Sending sms..."
}
}
class Client {
private Service service
#Inject
Client(Service service) {
this.service = service
}
public void send() {
service.sendMessage()
}
}
public class ServiceProvider implements Provider<Service> {
Service get() {
return new SMSService() //Select implementation here?
}
}
public class MyModule extends AbstractModule {
#Override
protected void configure() {
bind(Service.class).toProvider(ServiceProvider.class).in(Scopes.SINGLETON)
}
}
public static void main(String...args) {
Injector injector = Guice.createInjector(new MyModule())
Client c = injector.getInstance(Client.class)
c.send()
}
In the above example, I'm forced to select which provider to use in Provider get() method. If I want to make this more dynamic, say for example, based on user preference, is there a way to wait select the provider at runtime and have guice inject it?
For these kind of problems, guice offers the MapBinder:
public class SnacksModule extends AbstractModule {
protected void configure() {
MapBinder<String, Snack> mapbinder
= MapBinder.newMapBinder(binder(), String.class, Snack.class);
mapbinder.addBinding("twix").toInstance(new Twix());
mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);
mapbinder.addBinding("skittles").to(Skittles.class);
}
}
With this binding, a Map can now be injected:
class SnackMachine {
#Inject
public SnackMachine(Map<String, Snack> snacks) { ... }
}
You can define all your services in advance, and than pick the concrete instance (or provider) from the map byconfigured value.
I am trying to re-use the service registrations in an assembly that I use through a few services in my solution. I follow the example listed from the NServiceBus website to implement the solution. When following that, unless I add the IWantCustomInitialization interface, my Init method (and IoC container implementation) appears not to function. When I have that interface implemented, I get exceptions (listed in SO questions here and here). I can't seem to get it to work that there are no exceptions AND the dependencies in my MessageHandler are being populated properly. Here is my current EndpointConfig implementation.
[EndpointSLA("00:00:30")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, UsingTransport<Msmq>, INeedInitialization {
public void Init() {
Configure.With().ObjectBuilderAdapter();
}
}
public class ObjectBuilderAdapter : IContainer {
readonly IDependencyInjector injector;
public ObjectBuilderAdapter(IDependencyInjectionBuilder dependencyInjectionBuilder) {
injector = dependencyInjectionBuilder.Create(); //This method does all the common service registrations that I am trying to re-use
//injector.RegisterType<ExtractIncomingPrincipal, PrincipalExtractor>();
}
public void Dispose() {
injector.Dispose();
}
public object Build(Type typeToBuild) {
return injector.Resolve(typeToBuild);
}
public IContainer BuildChildContainer() {
return new ObjectBuilderAdapter(new DependencyInjectorBuilder());
}
public IEnumerable<object> BuildAll(Type typeToBuild) {
return injector.ResolveAll(typeToBuild);
}
public void Configure(Type component, DependencyLifecycle dependencyLifecycle) {
injector.RegisterType(component);
}
public void Configure<T>(Func<T> component, DependencyLifecycle dependencyLifecycle) {
injector.RegisterType(component);
}
public void ConfigureProperty(Type component, string property, object value) {
if (injector is AutofacDependencyInjector) {
((AutofacDependencyInjector)injector).ConfigureProperty(component, property, value);
} else {
Debug.WriteLine("Configuring {0} for property {1} but we don't handle this scenario.", component.Name, property);
}
}
public void RegisterSingleton(Type lookupType, object instance) {
injector.RegisterInstance(lookupType, instance);
}
public bool HasComponent(Type componentType) {
return injector.IsRegistered(componentType);
}
public void Release(object instance) { }
}
public static class Extensions {
public static Configure ObjectBuilderAdapter(this Configure config) {
ConfigureCommon.With(config, new ObjectBuilderAdapter(new DependencyInjectorBuilder()));
return config;
}
}
Note: When I use the INeedInitialization interface, I get the ComponentNotRegisteredException when it's looking for IStartableBus.
When you are trying to swap the built in container, then you need to implement IWantCustomInitialization in the same class that implements IConfigureThisEndpoint.
You can use your own container and register all your types in there and tell NSB to use that container.
For example:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
var container = new ContainerBuilder().Build();
Configure.With()
.AutofacBuilder(container);
}
}