How GenericContainer from test containers should be parametrised? - testcontainers

I am getting errors in my IDE about:
Raw use of parameterized class 'GenericContainer' Inspection info:
Reports any uses of parameterized classes where the type parameters
are omitted. Such raw uses of parameterized types are valid in Java,
but defeat the purpose of using type parameters, and may mask bugs.
I've checked documentation and creators use everywhere raw type also:
https://www.testcontainers.org/quickstart/junit_4_quickstart/
f.e.:
#Rule
public GenericContainer redis = new GenericContainer<>("redis:5.0.3-alpine")
.withExposedPorts(6379);
I dont understand this approach. Can Anyone explain how should I parametrize GenericContainer<>?

Testcontainers uses the self-typing mechanism:
class GenericContainer<SELF extends GenericContainer<SELF>> implements Container<SELF> {
...
}
This was a decision to make fluent methods work even if the class is being extended:
class GenericContainer<SELF extends GenericContainer<SELF>> implements Container<SELF> {
public SELF withExposedPorts(Integer... ports) {
this.setExposedPorts(newArrayList(ports));
return self();
}
}
Now, even if there is a child class, it will return the final type, not just GenericContainer:
class MyContainer extends GenericContainer< MyContainer> {
}
MyContainer container = new MyContainer()
.withExposedPorts(12345); // <- without SELF, it would return "GenericContainer"
FYI it is scheduled for Testcontainers 2.0 to change the approach, you will find more info in the following presentation:
https://speakerdeck.com/bsideup/geecon-2019-testcontainers-a-year-in-review?slide=74

If you declare it like
PostgreSQLContainer<?> container = new PostgreSQLContainer<>(
"postgres:9.6.12")
.withDatabaseName("mydb");
the warning also goes away.

Related

Simple Injector: Register Conditional vs RegisterSingleton

Context: I am trying to capture multiple events in our api using serilog and the elastic search sink, these events include: GET actions(regular web api flow) as well as login attempts (Owin).
I am registering serilog like this:
container.RegisterConditional(
typeof(ICustomLogger),
c => typeof(CustomLogger<>).MakeGenericType(
c.Consumer?.ImplementationType ?? typeof(object)),
Lifestyle.Singleton,
c => true);
I am doing this for Owin registration:
app.Use(async (context, next) =>
{
using (var scope = container.BeginExecutionContextScope())
{
await next.Invoke();
}
});
Then when I call container.Verify(); the logger constructor gets called(as expected).
However when I call the logger from my OAuthAuthorizationServerProvider implementation like this:
var logger = ObjectFactory.GetInstance<ICustomLogger>(); the constructor gets called again, meaning the singleton is not really a singleton anymore, I am totally aware of the service locator antipattern(don't really have much time to refactor that piece right now), what is interesting is that if I change the logger registration to the following (getting rid of the type piece) then only one instance is created:
container.RegisterSingleton(typeof(ICustomLogger), typeof(CustomLogger))
The reason why I am trying to use the first option is because I want to be able to use .ForContext(typeof(T)); for serilog, and in case you are wondering how I am registering the ObjectFactory piece here it is:
Class:
public static class ObjectFactory
{
public static Container container;
public static void SetContainer(Container container)
{
ObjectFactory.container = container;
}
public static T GetInstance<T>() where T : class
{
return container.GetInstance<T>();
}
}
Registration(from my main bootstrapper):
ObjectFactory.SetContainer(container);
So my main question is: Why is only one instance created with RegisterSingleton but multiple are created with RegisterConditional and Lifestyle.Singleton?
The reason multiple instances are created has nothing to do with the fact that you are using your ObjectFactory, but simply because different closed versions of CustomLogger<T> are created:
A CustomLogger<object> is created when resolved as root type (by calling GetInstance<ICustomLogger>()
A CustomLogger<Service1> is created when ICustomLogger is injected into Service1.
Because a CustomLogger<object> is a different type than a CustomLogger<Service1>, it is impossible to have just one instance for both types. They both have to be created. This might seem weird, but consider these two classes:
public class Service1
{
public Service1(ICustomLogger logger) { }
}
public class Service2
{
public Service2(ICustomLogger logger) { }
}
At runtime, considering these two definitions, you want to create object graphs similar to the following:
var s1 = new Service1(new CustomLogger<Service1>());
var s2 = new Service2(new CustomLogger<Service2>());
In the above case, the CustomLoggers are not cached and are, therefore, effectively transients. You might try to rewrite this to the following, but that would not be the same:
ICustomLogger logger = new CustomLogger<Service1>();
var s1 = new Service1(logger);
var s2 = new Service2(logger);
Now both service get the same single instance. However, this means that Service2 gets a CustomLogger<Service1> which is not what you configured. You configured the dependency to be this:
typeof(CustomLogger<>).MakeGenericType(c.Consumer.ImplementationType)
Consequence of this is that when Service2 starts to log, it will look like if the messages are coming from Service1. This would likely be incorrect behavior. Otherwise, you could have simply called RegisterSingleton<ICustomLogger, CustomLogger<Service1>>().
This all means that the Singleton guarantee for a RegisterConditional that uses an implementation-type factory (as in your example) only holds for the specified closed generic type.
Note that RegisterConditional isn't the only part in Simple Injector where you see this behavior. The following registrations do have the same effect:
container.RegisterSingleton(typeof(IFoo<>), typeof(Foo<>));
container.RegisterDecorator(typeof(IFoo<>), typeof(FooDecorator<>), Lifestyle.Singleton);
In both these cases multiple instances of closed generic versions of Foo<T> and FooDecorator<T> can be created, but Simple Injector guarantees that there is only one instance of every closed-generic version of Foo<T>. With RegisterDecorator<T>, however, even that is not guaranteed. Consider this example:
container.Collection.Append<ILogger, Logger1>(Lifestyle.Singleton);
container.Collection.Append<ILogger, Logger2>(Lifestyle.Singleton);
container.RegisterDecorator<ILogger, LoggerDecorator>(Lifestyle.Singleton);
In this case, a collection of ILogger components is registered where each ILogger element will be wrapped with a LoggerDecorator. Because a LoggerDecorator can only depend on either Logger1 or Logger2, but not both, Simple Injector will have to create a new LoggerDecorator instance for each element. If the LoggerDecorator would be cached as a true Singleton, this would be the result:
private static ILogger logger = new LoggerDecorator(new Logger1());
private static loggers = new[] { logger, logger };
As there is only 1 single LoggerDecorator, this decorator depends on Logger1, which means that the collection of loggers only has two elements that both point to the same Logger1 instance. There is no Logger2.
This information is reflected in the following Simple Injector documentation sections:
Aspect-Oriented Programming - Applying Lifestyles to Decorators
Lifetime Management - Generics and Lifetime Management

Using Service methods inside Utils class [Spring and Kotlin]

I have faced a well-known scenarios whereby I really need to move a number of utilities private functions (that should not have been there in the first place) from my Service class to a utility class. My question is around using service methods in a utility class. I have attempted at the following refactoring:
class Utils(
val serviceIneed : ServiceIneed) {
companion object {
private val someMapper = ObjectMapperConfig.mapper
}
fun someUtility(): ResponseEntity<Any> {
// lots of stuff
return serviceIneed.someFunction()
}
}
Then this is the other service where I need to use the method I have moved to the newly created utility class:
class anotherService(
private val serviceIneed: ServiceIneed
) {
fun someMethod() {
// lots of things happening
val utilityUsage = Utils(serviceIneed).someUtility()
}
}
Is this the correct way to go about this? Can you recommend any approach on refactoring service classes in a way that only service-oriented methods and not helper ones remain in my Service class?
Thank you

Writing a testable Finagle Resolver

I'd like to test a Finagle Resolver properly.
Let's get a sample code:
import com.twitter.finagle.{Addr, Address, Resolver}
import com.twitter.util._
class DummyResolver extends Resolver {
override val scheme: String = "sample"
override def bind(arg: String): Var[Addr] = {
val delegate = SomeFactory.fromArgs(arg).build()
Var.async(Addr.Pending: Addr)(u => addrOf(u)(delegate))
}
}
The use of a static factory prevents me from unit-testing the resolver.
As far as I know, the only way to provide the resolver to Finagle is to declare it into the com.twitter.finagle.Resolver file in META-INF/services. Thus, I cannot provide an instance myself.
Given those constraints, how to design the resolver to either:
be able to provide an instance of the delegate,
or be able to properly test the behavior (and mock the delegate)?

Dependency Injection with Interface implemented by multiple classes

Update: Is there a way to achieve what I'm trying to do in an IoC framework other than Windsor? Windsor will handle the controllers fine but won't resolve anything else. I'm sure it's my fault but I'm following the tutorial verbatim and objects are not resolving with ctor injection, they are still null despite doing the registers and resolves. I've since scrapped my DI code and have manual injection for now because the project is time sensitive. Hoping to get DI worked out before deadline.
I have a solution that has multiple classes that all implement the same interface
As a simple example, the Interface
public interface IMyInterface {
string GetString();
int GetInt();
...
}
The concrete classes
public class MyClassOne : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
public class MyClassTwo : IMyInterface {
public string GetString() {
....
}
public int GetInt() {
....
}
}
Now these classes will be injected where needed into layers above them like:
public class HomeController {
private readonly IMyInterface myInterface;
public HomeController() {}
public HomeController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
public class OtherController {
private readonly IMyInterface myInterface;
public OtherController() {}
public OtherController(IMyInterface _myInterface) {
myInterface = _myInterface
}
...
}
Both controllers are getting injected with the same interface.
When it comes to resolving these interfaces with the proper concrete class in my IoC, how do I differentiate that HomeController needs an instance of MyClassOne and OtherController needs an instance of MyClassTwo?
How do I bind two different concrete classes to the same interface in the IoC? I don't want to create 2 different interfaces as that breaks the DRY rule and doesn't make sense anyway.
In Castle Windsor I would have 2 lines like this:
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());
This won't work because I will only ever get a copy of MyClassTwo because it's the last one registered for the interface.
Like I said, I don't get how I can do it without creating specific interfaces for each concrete, doing that breaks not only DRY rules but basic OOP as well. How do I achieve this?
Update based on Mark Polsen's answer
Here is my current IoC, where would the .Resolve statements go? I don' see anything in the Windsor docs
public class Dependency : IDependency {
private readonly WindsorContainer container = new WindsorContainer();
private IDependency() {
}
public IDependency AddWeb() {
...
container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));
return this;
}
public static IDependency Start() {
return new IDependency();
}
}
I hope you can use service overrides.
Ex.
container.Register(
Component.For<IMyService>()
.ImplementedBy<MyServiceImpl>()
.Named("myservice.default"),
Component.For<IMyService>()
.ImplementedBy<OtherServiceImpl>()
.Named("myservice.alternative"),
Component.For<ProductController>()
.ServiceOverrides(ServiceOverride.ForKey("myService").Eq("myservice.alternative"))
);
public class ProductController
{
// Will get a OtherServiceImpl for myService.
// MyServiceImpl would be given without the service override.
public ProductController(IMyService myService)
{
}
}
You should be able to accomplish it with named component registration.
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>().Named("One"));
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>().Named("Two"));
and then resolve them with
kernel.Resolve<IMyInterface>("One");
or
kernel.Resolve<IMyInterface>("Two");
See: To specify a name for the component
Typically DI containers follow Register, Resolve and Release patterns. During the register phase there are two steps. The first is to specify the mapping as you are doing. The second step is to specify the rules which govern which to inject where.
This problem is very common when we try to address Cross cutting concerns using decorators. In these situations, you have multiple classes(decorators) implementing a single interface.
Briefly, we need to implement IModelInterceptorsSelector which allows you to write imperative code that decides which Interceptor to apply to which types or members.
This is elaborately described in the book Dependency Injection in .Net book by Mark Seemann. Look for chapter 9 interception or search for the above interface.
I am not an expert at this, but was searching for the exact same problem and found the ans in the above book.
Hope this helps.
Regards
Dev1

Why doesn't Mockito's when() get triggered?

I need to test a service class, but when I try to mock the dao class, it doesn't get triggered, thus not able to use ThenReturn().
I think that the problem is because I use an interface for my Dao and #Autowired in the service class (Spring MVC 3.1):
The interface:
public interface TestDao {
int createObject(Test test) throws NamingException;
}
The implementation:
#Repository
public class TestDaoImpl implements TestDao {
#Override
public int createObject(Test test) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new InsertNewTest(test), keyHolder);
return ((java.math.BigDecimal)keyHolder.getKey()).intValue();
}
}
The service:
public class RegTest {
#Autowired
TestDao testDao;
public int regTest(int .....) {
.
.
int cabotageId = testDao.createObject(test);
}
}
In the test I have:
#RunWith(MockitoJUnitRunner.class)
public class TestRegService {
#InjectMocks
private RegTest regTest = new RegTest();
#Mock
TestDao testDao;
#Test()
public void test() {
.
when(testDao.createObject(null)).thenReturn(100);
.
}
testDao.createObject(null) returns 0 (due to being mock'ed) and not 100 as I is trying to achieve.
Can anybody help, please?
Problem solved!
It was the passing test-object to createObject() that did not match. Using
testDao.createObject(any(Test.class))
did the trick!
If your test is actually passing a value to createObject, then when(testDao.createObject(null)... never gets matched. Rather than matching on null, you could match any instance of Test with testDao.createObject(any(Test.class))...
Also when you tried later to supply new Test() as the argument to match, it will literally try to match on that exact instance of Test, but presumably your real code is new-ing up a different one. So the use of Matchers.any(Test.class) as the parameter to match is the way to go.
Mockito injection mechanism don't know about Spring #Autowired or CDI #Inject annotations. It just tries to find the best candidate given the type and the name of the mock, and it can lookup private fields too. See the javadoc of #InjectMocks : http://docs.mockito.googlecode.com/hg/1.9.0/org/mockito/InjectMocks.html
The semantic you are using is correct, though if you are experiencing issues, I would rather look for incorrect interactions or incorrect arguments.
Are you sure the test variable in regTest.regTest(int...) is really null when passed to testDao.createObject(test) ?
I don't know if this is a typo in the example, but you have RegTest.regTest() calling createTest() rather than createObject(). Otherwise, I don't think #Autowired has anything to do with it, since your test itself is not running in a container with Spring management. If it is not a typo, and createTest is in fact a real and different method from createObject, then the default behaviour of a mocked object in Mockito is to return the appropriately-typed zero for numeric return types.
I think that you're right about the autowire not getting called. You could inject the dao yourself using the setTestDao() call instead. Mockito also supports spy which allows you to trace the objects code and just replace functions instead.

Resources