Why testcontainers restarts contener between test classess - integration-testing

I've noticed that test containers is restarting container.
It happens when I am executing tests, between Test classes. First test class tests connects to container without issue, but then in next class port which is bind to host is incremented (cause new container is up), and my Spring integration test dosn't know that, which cause to rest test fails.
How to persist container for all tests?
Please help
The container inside port (5432, as it is postgressql) is the same all the time.

If you want to reuse containers between test classes you need to declare it as static field and initialize once, as example
#ContextConfiguration(initializers = BaseIntegrationTest.Initializer.class)
class BaseIntegrationTest {
static KafkaContainer kafkaContainer;
static {
kafkaContainer = new KafkaContainer();
kafkaContainer.start();
}
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertyValues.of(
"kafka.bootstrapServers=" + kafkaContainer.getBootstrapServers()
).applyTo(applicationContext);
}
}
}

Related

How to keep a statefull bean clean or reset during a #QuarkusTest?

I test a statefull bean with a #QuarkusTest. It keeps a certain state. Obviously, I would like to have a fresh bean for every test. At the moment, each test might modify he current state, which is the effective for a oncoming test. This is highly undersireable and breaks my tests.
Is there a way to force a new bean clean bean getting injected for every test when running a #QuarkusTest?
Eg. A very basic subscription service, which holds the current subscription to avoid double subscriptions:
#ApplicationScoped
public class SubscriptionService {
#Inject
DeviceClient deviceClient;
private final Set<String> subscribedDevices = new HashSet<>();
public void subscribe(String deviceId, Consumer<RadarFrame> consumer){
if(subscriptions.contains(deviceId)){
return;
}
deviceClient.subscribe(deviceId, consumer);
subscriptions.add(deviceId);
}
public void unsubscribe(String deviceId, Consumer<RadarFrame> consumer){
deviceClient.unsubscribe(deviceId);
subscriptions.remove(deviceId);
}
}
I could manually unsubscribe the device after each test, which is a bad small as I use potention untested implemented logic for setup/teardown. It would be nice if a injected bean could be reinitialized before each test on a #QuarkusTest.
Or did I miss another clean option?
#ApplicationScoped beans will be there for the entire life of the container.
The recommended way to do this is to create a reset() method in the bean to later be called in tests. With JUnit 5 this would be something like:
#AfterEach
void tearDown() {
subscriptionService.reset();
}
You can make that method package friendly to limit it's usage.

Blazor. Task from another service

I'm studying blazor server.
Deployed a solution from a standard vs template.
Created two server-side services, TestService1 and TestService2.
In TestService1 i have task
GetMyData()
How can i call with task from TestService2?
If i trying
var serv1 = new TestService1()
i have to fill in all the variables of the constructor that is in TestService1.
What is easiest way?
In line with the comment on your question, the best way to go about this in Blazor is to utilize the built-in dependency injection mechanism.
I assume that your services look like the following:
public class TestService1
{
public object GetMyData()
{
}
}
public class TestService2
{
private readonly TestService1 _testService1 { get; set; }
public class TestService2(TestService1 ts1)
{
_testService1 = ts1;
}
public void DoesSomething()
{
var data = _testService1.GetMyData();
//...
}
}
First, you'd need to register these with Blazor at startup, so in your Startup.cs in the ConfigureServices method, add the following, assuming you have an empty constructor available for TestService1:
services.AddSingleton<TestService1>();
Because you'll need to instantiate an instance of TestService1 into TestService2 to call methods on it, you'll have to handle registration of TestService2 differently since you'll need to procure an instance of TestService1 from the DI service to instantiate it:
services.AddSingleton<TestService2>(s => {
var testService1 = s.GetService<TestService1>();
return new TestService2(testService1);
});
It's possible you may need to scope the services differently (e.g. used scoped instead of singletons). You can read about the differences here.
Now something is presumably calling TestService2 to kick all this off, so let's pretend it's running in a component in your Blazor app. You'd inject TestService2 into the component with the following:
#inject TestService2 _testService2
<h1>Hello!</h1>
#code {
protected override void OnInitialized()
{
_testService2.DoesSomething();
}
}
As part of the initialization then of this component, it'll automatically inject a TestService2 instance (based on the scoping you specified at DI initialization) to your component and will call the DoesSomething method on it. When injected, it looks to DI to instantiate the TestService1 service to the constructor as you've also specified, leaving it free to call that method and the call commences as intended.
Please let me know if you'd like any clarification somewhere!

How to get current IUnityContainer to register more types

I have a windows service that is using Microsoft's Unity 2.1, typically all the types are registered during the service startup. (program.cs)
There is also a Windows Service Class. I need to get access to current IUnityContainer in this service class to register a type.
How do i get access to IUnityContainer so that i can register more types?
There is no concept of Current IUnityContainer as you can have multiple of these, even though this is a very rare thing, in my experience, if you don't count the child containers. There are however multiple ways you can keep a hold on your container though. You can do what's suggested in this answer, by doing that at a higher level, but I'd recommend against it. What I've taken a habit of doing is:
In the non-main projects, I create a static class such as:
static class UnityRegistrator
{
public static void Register(IUnityContainer container)
{
// Whatever Registrations for types in this assembly.
container.RegisterType<INamedClass, ClassLibrary2>(
new InjectionConstructor(
new ResolvedParameter<string>("Foo")));
}
}
And in the main project, for example in your program.cs:
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
MyAssembly.UnityRegistrator.Register(container);
var namedClass = container.Resolve<INamedClass>();
namedClass.Whatever();
}
static void Register(IUnityContainer container)
{
// Whatever Registrations for types in this assembly.
container.RegisterType<string>("Foo", "Bar");
}
}

Using an existing IoC Container in SignalR 2.0

How can I use an existing IoC with SignalR 2.0?
From the tutorial, it seems I need to setup a class to be called from OWIN via an attribute:
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
public class Startup
{
public void Configuration(IAppBuilder app /*HOW AM I GONNA GET UNITY CONTAINER HERE?*/)
{
var hubConfig = new HubConfiguration()
{
EnableJSONP = true,
EnableDetailedErrors = true,
EnableJavaScriptProxies = true,
Resolver = new SignalRUnityDependencyResolver(container)
};
// Any connection or hub wire up and configuration should go here
app.MapSignalR(hubConfig);
}
}
}
The problem here is that I already have a container, that's boot strapped and there are singleton instances in the container that needs to be shared with the MVC app shared under the same host.
However the trouble here is that unlike before, it doesn't look like I can call the MapSignalR method from my own code. Rather I need to rely on OWIN to do this for me. However OWIN is not aware of the container that I already setup.
What's the best way to resolve this? I have some very crude ideas how to hack a solution together using static variables to hold some of these - but I hate the very thought of it. The code will be brittle and order of operation could easily introduce a subtle bug.
Is there a way to get a hold of the IAppBuilder instance without having OWIN invoke the above method? This way I can control better when SignalR gets initialized and I can pass my own IoC into the configuration.
In my case I have created a custom hub activator which uses a shared container between my app and signalR (by constructor injection) that way you´ll have single composite root for the whole application.
try the following:
public class CustomHubActivator : IHubActivator
{
private readonly Container _container;
public MseHubActivator(Container container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return _container.GetInstance(descriptor.HubType) as IHub;
}
}
register your custom hub activator when you´re bootstrapping your app (maybe the global.asax)
GlobalHost.DependencyResolver.Register(typeof (IHubActivator),
() => new CustomHubActivator(Container));
that´s much simplier solution rather than to configure again the signalR dependencyResolver

Autofac, ASP.NET and Microsoft.Practices.ServiceLocation

I've been working thru the details of implementing IoC in my web apps but in a way that leverages Microsoft.Practices.ServiceLocation. I am specifically using Autofac and the asp.net integration, but I wanted to leave myself open to other containers. Along the lines of this question, i was concerned about how to access the container in my web app code.
I have a 'core' library that primarily defines interfaces to be resolved. This core library is used by my web app and other apps as well. Very handy to have common interfaces defined. I thought this was an excellent place to put access to the IoC container, and I did so with a static class. The trick is injecting the container into the static class.
It's tricky in a web environment becuase the container may be different for each request, while in a non-web app it will probably be the same all the time. At first I tried injecting the container direclty with a method but that quickly failed on the next web request! So I came up with this:
public static class IoCContainer
{
public static void SetServiceLocator(Func<IServiceLocator> getLocator)
{
m_GetLocator = getLocator;
}
static private Func<IServiceLocator> m_GetLocator = null;
public static T GetInstance<T>(string typeName)
{
return m_GetLocator().GetInstance<T>(typeName);
}
}
Now in my global.asax.cs I do this:
protected void Application_Start(object sender, EventArgs e)
{
var builder = new Autofac.Builder.ContainerBuilder();
... register stuff ...
var container = builder.Build();
_containerProvider = new Autofac.Integration.Web.ContainerProvider(container);
Xyz.Core.IoCContainer.SetServiceLocator(() =>
new AutofacContrib.CommonServiceLocator.AutofacServiceLocator
(_containerProvider.RequestContainer));
}
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
static IContainerProvider _containerProvider;
And calls to resolve dependences look like
var someService = Xyz.Core.GetInstance<ISomeService>();
So rather than pass a specific container I pass a delegate that knows how to GET a container. For non-web applications the delegate would probably just return what builder.Build() serves up.
My question to the experts is, does this make sense? I have an easy way to get to something that can resolve dependencies without knowing what the container product is or where the container itself comes from. What do you think?
We use a similar pattern mostly due to the fact that IoC was introduced into a non-DI architecture. Thus the need to be able to explicitly call the container to get services, which basically is the Factory pattern.
The true benefit of IoC is achieved when all dependencies can be injected and your code no longer have a dependency on the service locator. Autofac.Integration.Web have handlers that will perform injection into your page objects which will make the static service locator obsolete. Imo this is the preferred way, though (as in our case also) service locator cannot always be avoided.
That said, since you already have isolated your app from the container using IoCContainer class, I see no reason to have the additional abstraction of AutofacServiceLocator within IoCContainer. Bottom line is that IoCContainer is already your service locator and should be "allowed" direct access to the container implementation.
Here is my take on your service locator class:
public static class IoCContainer
{
private static IContext GetContainer()
{
var cpa =
(IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
return cpa.ContainerProvider.RequestContainer;
}
public static T GetInstance<T>()
{
return GetContainer().Resolve<T>();
}
}

Resources