Implement class with private constructor in Kotlin - kotlin

I'd like to write a little stub for a service class. The reason is, that I don't want to push the secret API keys that the service class needs to the CI and I don't want the service class in the CI to run against the external service anyways.
However, the service class is non-abstract and has a private constructor.
When I try to create my stub class like:
open class FirebaseMock: FirebaseMessaging {
// implemented functions go here
}
it says
This type has a constructor, and thus must be initialized here
If I try to initialize it like:
open class FirebaseMock: FirebaseMessaging() {
// implemented functions go here
}
it goes
Cannot access '<init>': it is private in 'FirebaseMessaging'
Which is true:
private FirebaseMessaging(Builder builder) {
...
All I want to do is make my stub class formally a subclass of FirebaseMessaging to use it as placeholder, that mocks the FirebaseMessaging-Functionality when the API keys are not present.
How can I just implement a non-abstract, non-interface class, that has a private constructor nonetheless.
My current solution is a wrapper, which works but is not as nice.
Mockito etc. does not seem like a good solution, since this is still in the productive code.

Related

Role of private & non-private initializers in (Dart) private & non-private class constructors?

I'm new to OOP currently with intermediate level of understanding. I'm constantly gaining ground by learning Dart and C#. I'm also exploring the design patterns to really understand how it all clicks together based on different scenarios. As for now I'm trying to make sense of following 4 scenarios related to class constructors. I understand the implications of underscore at constructor level and at initializer level. But I am looking for something that may seem quite obvious and clear to experienced programmers out there. Please share your valuable insights as I don't know what I'm missing here.
Scenario 1: Private Constructor with no initializer
I know this is different from Singleton. Singleton allows single instantiation, this below does not even once. Is there something more to it?
Real World Example:
class Firebase {
// Ensures end-users cannot initialize the class.
Firebase._();
...
}
Scenario 2: Private Constructor with optional public or non-private initializer
What's the use of this type of private constructor that has non-private initializer (this.app)? Why have a non-private initializer (this.app) in a private constructor? What is achieved through this?
Real World Example:
class FirebaseAuth extends FirebasePluginPlatform {
/// The [FirebaseApp] for this current Auth instance.
FirebaseApp app;
FirebaseAuth._({required this.app})
: super(app.name, 'plugins.flutter.io/firebase_auth');
/// Returns an instance using the default [FirebaseApp].
static FirebaseAuth get instance {
FirebaseApp defaultAppInstance = Firebase.app();
return FirebaseAuth.instanceFor(app: defaultAppInstance);
}
...
}
Scenario 3: public Constructor with private initializer
Why have a private property in a non-private constructor? What is achieved through this?
Fictitious Example:
class Constructify {
Map<String,dynamic> _property;
Constructify(this._property);
...
}
Scenario 4: Private Constructor with private initializer
Why have a private initializer at all when the constructor itself is private? What is achieved through this?
Real World Example:
class FirebaseApp {
/// A [FirebaseApp] instance can only be accessed from a call to `app()` [FirebaseCore].
///
/// This constructor ensures that the delegate instance it is constructed with is one which extends [FirebaseAppPlatform].
FirebaseApp._(this._delegate) {
FirebaseAppPlatform.verifyExtends(_delegate);
}
final FirebaseAppPlatform _delegate;
...
}
Scenario 1: _ in Dart means the variable/method/function/constructor is package private. So as long as we are inside the same package, we are allowed to use the field. So in Scenario 1 this actually means we can only create Firebase objects if we call the constructor from the package where Firebase has been declared. This will also prevent you from extending the class in another package since we cannot call the constructor on the Firebase class we are extending from.
Scenario 2: The package private constructor ensures that objects can only be created by code from the same package. The named app parameter is marked required so it is not optional. After the object has been created, you can in this case change the app variable. I don't know if this makes sense in this scenario but you can do it. I would properly in most cases mark app as final.
Scenario 3: The private field can be set to a value using the constructor but since the field is package private, we can ensure nobody outside our package can access the field afterwards.
Scenario 4: A package private constructor is used by some other code in the same package. If you want to ensure only your own package are allowed to create new objects of FirebaseApp and don't want code outside your package to get access to the field _delegate, you can do what this example does.

How to receive IHubContext out of Dependency Injected classes?

I want to send message from Service A using SignalR when some event occures (for example, message from Service B received).
So hub method needs to be called from some sort of handler, that not constructed using Dependency Injection. How I can do this?
So far, I tried and read about the following things:
I can inject context into Controller and lead it to my handler. I probably can do that, but passing hub context from the top (controller class) to the bottom (handler class) is not the best approach, which adds a lot of dependencies to the classes that should not be aware of this context, so I would like to avoid that.
I can inject my IHubContext in "any" class, but then, the thing is, how to get an instance of that class on my handler?
Add Static method to class with injected context!? Well, that works until you have 1 client because with new client static property is going to be overwritten.
So I cannot imagine, how handler can use dependency injected IHubContext.
Probably, someone did that before and have an example of how to truly inject context into any class.
Thank you in advance and any additional information will be provided, if necessary.
Answer 1
Here is one possible solution. Implement a factory pattern. Create a factory that knows how to create your handler. Inject the IHubContext in the factory. You can use a few approaches that way:
Construct the Handler by passing in the IHubContext
Create a public property in the Handler and set the IHubContext
Create a method in the Handler and pass the IHubContext as a parameter
You can decide whichever approach suits you. Inject that factory in the controller via DI, and get the handler using the factory method. That way you are not exposing the IHubContext. Please see the code below
public interface IHandlerFactory
{
Handler CreateHandler();
}
public class HandlerFactory : IHandlerFactory
{
private IHubContext _hubContext;
public HandlerFactory(IHubContext context)
{
_hubContext = context;
}
public Handler CreateHandler()
{
return new Handler(param1, param2, _context);
}
}
Then in the entry point, controller/service, inject the factory via DI
public class MyController : Controller
{
private Handler _handler;
public MyController(IHandlerFactory factory)
{
_handler = factory.CreateHandler();
}
}
Then you can use that _handler in the other methods. I hope this helps.
Answer 2
Another possible solution is to use IHostedService if it's possible at all for you. Please see a solution to a GitHub issue, provided by David Fowler here, that I think somewhat relevant to your scenario.

Controlling lifetime of objects created by factory generated by ToFactory()

I am using the following Ninject related nuget packages in an MVC 5 WebAPI application:
Ninject.MVC5
Ninject.Extensions.Factory
ninject.extensions.conventions
I have a simple repository and a corresponding factory class like so:
public interface ITaskRunner
{
void Run();
}
public interface IRepository<T> where T: class
{
T[] GetAll();
}
public interface IRepositoryFactory<T> where T: class
{
IRepository<T> CreateRepository();
}
I have setup the Ninject bindings using ToFactory() from Ninject.Extensions.Factory like so:
kernel.Bind<ITaskRunner>().To<TaskRunner>().InSingletonScope();
kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
kernel.Bind<IRepositoryFactory<Contact>>().ToFactory();
I am using the factory in the following class:
public class TaskRunner : ITaskRunner
{
//MyTask is a simple POCO class(not shown for brevity)
IRepositoryFactory<MyTask> repoFactory = null;
IRepository<MyTask> repo = null;
public TaskRunner(IRepositoryFactory<MyTask> repoFactory)
{
this.repoFactory = repoFactory;
repo = repoFactory.CreateRepository();
}
//implementation elided
}
I am noticing that the call to repoFactory.CreateRepository() always returns the same instance of the factory (dynamic proxy) that Ninject generates.
Question : Is there a way to change/control this behavior and set a "lifetime" such as Transient, PerThread etc. for the instance that "CreateRepository" returns?
In this particular case, tasks might be processed asynchronously on multiple threads and the repository is not thread safe and hence singleton behavior for the instance returned from "CreateRepository" is not desirable.
I'm not sure what you are trying to achieve, but results you are seeing are quite expected because your TaskRunner is bound as Singleton (so constructed once), and you retrieve your repository in the TaskRunner constructor, which again happens once, and so repo is always the same instance. Note this happens regardless of how you bind IRepository and IRepositoryFactory, see Captive Dependency post by Mark Seemann for details http://blog.ploeh.dk/2014/06/02/captive-dependency/.
In fact, if you need to create repo in the constructor, you could just inject IRepository itself. The power of the Factory extension lies in the fact that it allows to resolve instances at runtime, not construction time. For example, if your TaskRunner has Run() method, you can create repository in it, so each task to run can have its own instance.

Dropwizard Integrated Testing with Mocks for DB

First: Yes I read this https://dropwizard.github.io/dropwizard/manual/testing.html
I want to do some integration testing and tahts why I have to start the entire application. Now the problem is, that I have some interfaces to the "outside world" like DB or one internal Rest-Client, who speaks with one remote app. I want to mock them with mockito. Normally thats no problem.
Now my question: How can I start entire application with mocked DB and mocked client?
The problem at the moment is, that I get this DB connection and client from my configuration class via getDBClient() ... and I'm not willing to build in some test code in my config, because its production code. So if I start the entire app via DropwizardAppRule, the app tries to connect to database, but in testing enviroment, there is no DB available.
Is there a easy way to say: Start my app but if you call DB or client, then use this XY mock?
What I tried yet:
One new class "ExtendedService extends Service extends Application" and one "ExtServiceConfiguration extends ServiceConfiguration", but without any success. But I having trouble if I override some methods in the config class returning the mock. It does not fit all together.
At the moment I read the docs for mockito spy, perhaps this can help, but I'm not sure how to use this in the DW integrated tests. I now try to mock 2 of my configuration class methods to return a DB and client mock. Perhaps someone can help me, how to mock the TestConfiguration in the next example code:
#ClassRule
public static final DropwizardAppRule<TestConfiguration> RULE =
new DropwizardAppRule<TestConfiguration>(MyApp.class, resourceFilePath("my-app-config.yaml"));
EDIT:
#ClassRule
public static final DropwizardAppRule RULE = new DropwizardAppRule(.....)
In #BeforeClass I do the following:
ServiceConfiguration oldConfig = RULE.getConfiguration();
ServiceConfiguration spy = Mockito.spy(oldConfig);
//Then DB mocking
IDatabaseLayer dBMock = mock(IDatabaseLayer.class);
Mockito.when(dBMock.isConnected()).thenReturn(true);
... // other mocking functions for DB
//this is important, it say, that the mocked config class should use the mocked DB
Mockito.doReturn(dBMock).when(spy).getDataBaseLayer(); // my configuration class has this method, so mocking config class with last created dbMock
// do other mockings if needed
Thats all I had done to start entire application.
If you really want to run an integration test, I suggest using a memory or temporary database like h2 or sqlite, if you can, by creating a new yml file with the relevant settings; and use a mocked http service such as Wiremock.
Otherwise stick to ResourceTestRules as th3morg suggests.
If you want to mock specific things but still keep the whole flow of dropwizard, then you need to manage your own Application instance and make it possible to inject your dependencies to your Application class. Because DropwizardAppRule doesn't give you that flexibility.
Example: You want to be able to override the dependencies on your application class.
public class MyApplication extends Application {
private FooManager fooManager;
// Need to leave an empty constructor for other uses
public MyApplication(){
}
public MyApplication(FooManager fooManager){
this.fooManager = fooManager;
}
#Override
public void run(Configuration configuration, Environment environment) throws Exception {
if(fooManager == null){
fooManager = new FooManagerImpl();
}
// stuff
}
}
Then on your test, you create your own instance (or you can create a rule class by copying and modifying DropwizardAppRule source code. Edit: Looks like you can inherit DropwizardTestSupport class and override public Application<C> newApplication().).
#Test
public void test(){
FooManager fooManager = mock(FooManager.class);
MyApplication myApplication = new MyApplication(fooManager);
myApplication.run("server", "config.yml");
}
I think that you should be using io.dropwizard.testing.junit.ResourceTestRule instead, which is used for testing Jersey resources (i.e. making calls to your REST API endpoints). The DropwizardAppRule will start the whole application and stop it at the end of your test. That class seems to be intended for end-to-end testing in which you would not do any mocking whatsoever.

Late binding with Ninject

I'm working on a framework extension which handles dynamic injection using Ninject as the IoC container, but I'm having some trouble trying to work out how to achieve this.
The expectation of my framework is that you'll pass in the IModule(s) so it can easily be used in MVC, WebForms, etc. So I have the class structured like this:
public class NinjectFactory : IFactory, IDisposable {
readonly IKernel kernel;
public NinjectFactory(IModule[] modules) {
kernel = new StandardKernel(modules);
}
}
This is fine, I can create an instance in a Unit Test and pass in a basic implementation of IModule (using the build in InlineModule which seems to be recommended for testing).
The problem is that it's not until runtime that I know the type(s) I need to inject, and they are requested through the framework I'm extending, in a method like this:
public IInterface Create(Type neededType) {
}
And here's where I'm stumped, I'm not sure the best way to check->create (if required)->return, I have this so far:
public IInterface Create(Type neededType) {
if(!kernel.Components.Has(neededType)) {
kernel.Components.Connect(neededType, new StandardBindingFactory());
}
}
This adds it to the components collection, but I can't work out if it's created an instance or how I create an instance and pass in arguments for the .ctor.
Am I going about this the right way, or is Ninject not even meant to be be used that way?
Unless you want to alter or extend the internals of Ninject, you don't need to add anything to the Components collection on the kernel. To determine if a binding is available for a type, you can do something like this:
Type neededType = ...;
IKernel kernel = ...;
var registry = kernel.Components.Get<IBindingRegistry>();
if (registry.Has(neededType)) {
// Ninject can activate the type
}
Very very late answer but Microsoft.Practices.Unity allows Late Binding via App.Config
Just in case someone comes across this question