Instantiate class manually every time when method get called NestJS - nestjs

I have a service which needs to instantiate other class every time when method get called.
E.g.
class SomeClass { ... }
#Injectable()
class SomeService {
constructor(...) {}
async doStuff() {
new SomeClass() // new instance every time;
}
}
How can i inject it (SomeClass) properly, and create instance of it every time when method doStuff get called?

If you're needing to instantiate the class everytime for only that method, then what you're already doing is fine. No reason to bring in dependency injection if you're going to be instantiating that class, because Nest's DI system will instantiate it for your otherwise

Related

PHPUnit Stubbing A Method Call From Another Class

I have chosen PHPUnit to do some testing on a bot I built. This is the first example from the Test Doubles chapter:
`
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class StubTest extends TestCase
{
public function testStub(): void
{
// Create a stub for the SomeClass class.
$stub = $this->createStub(SomeClass::class);
// Configure the stub.
$stub->method('doSomething')
->willReturn('foo');
// Calling $stub->doSomething() will now return
// 'foo'.
$this->assertSame('foo', $stub->doSomething());
}
}
`
I see how doSomething() has been stubbed out, which is close to what I am trying to achieve.
How do I stub out an object method from another class that was created inside SomeClass::class?

What is the right way to export the class to be extended from other classes NodeJs?

Base class looks like this:
class BaseReport {
constructor(reportName) {
this.reportName = reportName;
}
async generateReport(accountId, request) {
let results = await this.getDataFromDb(request);
results = this.formatResults(results);
return updatedResults;
}
formatResults(data) {
//Some logig here
return result
}
getDataFromDb(request) {
//Logic to get data from database
return errorRequest;
}
}
module.exports = BaseReport;
The I have another class that extends Base class:
const BaseReport = require("./base.service");
class DataReport extends BaseReport {
constructor() {
super('dataReport');
}
formatResults(data) {
//Logic to format results in a different way
return data;
}
}
module.exports = new DataReport();
So far everything works well. DataReport class doesn't need to implement the method getDataFromDB because it is inherited from BaseReport class.
The problem starts when I am writing unit/integration tests.
When I try to stub function getData() it is not working (it is not being stubbed but instead it is calling the method and making the database call.
I understand WHY is happening... In BaseReport class I am exporting the class itself. So when I create an object on my unit tests and try to stub the function, that is not the same method and object which is initialized when the application is running. Every time you use the keyword "new" creates a new object and has its own methods.
If I want to stub a method from DataReport class it works fine because in there I am exporting an object of that class (module.exports = new DataReport();). In this case, it can only exist one copy of the object and so only one copy of the methods as well.
Now I can not do the same for BaseReport class because my understanding is that you CAN NOT extend BaseReport class if I exported a new object (module.exports = new BaseReport();).
What is the proper way to implement this in order to also have the unit tests working??

Singleton service inside a class instance

I have a class in which I need to use a service but this class needs to be instantiated.
It's like this:
class EntrySubject implements ISubject {
constructor(entry: EntryEntity) {}
}
Since I need a service there, I could do this:
class EntrySubject implements ISubject {
constructor(entry: EntryEntity, entryService: EntryService) {}
}
And when using this class inside EntryService I would just instantiate my class as:
const entrySubject = new EntrySubject(entry, this);
But in this case, as far as I understand, every new subject instance would have its own EntryService, but what should I do if I want a single instance of EntryService?
All you have to do is to decorate your EntitySubject, or any other class that you wish to inject, with #Injectable(), and have that class in the 'providers' array of the module. That way, when the constructor has the class in its params, nest will inject a singletone instance of that class.
Please note that when using #Injectable, the default value that is used is #Injectable({scope: DEFAULT}) which means a singletone instance of the class.
For more info on injection scopes visit :
https://docs.nestjs.com/fundamentals/injection-scopes

Calling Method of class within it

// What is the technical reason behind this scenarios..?
You're trying to use a statement other than a declaration directly inside the class - rather than within a method. When did you expect the method to get called?
Basically all you can have directly within a type is a bunch of declarations - methods, variables, constructors, events, nested types etc. Method calls (or any other statements) which aren't part of a declaration have to be written within methods, constructors etc.
Method call statement can not be part of a class declaration, but only within Function members declarations scope, such as Methods, Properties, Constructors etc.
For example:
public class ExampleClass
{
private void SayHelloWorld()
{
Console.Writeline("Hello World!");
}
public void CallSayHelloWorldMethod()
{
this.SayHelloWorld();
}
}
At the above example you can see that I call the SayHelloWorld method within the CallSayHelloWorldMethod metod.
Update:
The closest thing I can think of in your case is to use the class's constructor where your method call will be executed as soon as you'll instantiate your class:
public class ExampleClass
{
//The class constructor
public ExampleClass()
{
this.SayHelloWorld();
}
private void SayHelloWorld()
{
Console.Writeline("Hello World!");
}
}
And when you instantiating it, it will be immediately called:
//Your method call will be executed here
ExampleClass exampleClass = new ExampleClass();
You have a few problems... This won't even compile as you are trying to call the method obj.m1() in the class definition.
A obj = new A();
obj.m1(); // Why this code wont work??? --> This must be inside a method
When you create an instance of a class it will create a new member variable called obj which is an instance of A --> A obj = newA() above;
You will now be able to call obj's methods as in your second example.
Also, in order to get this to compile you will need to fix the m2 method:
public void m2() { //--> should have a curly brace
obj.m1(); // But This will work.
}

Can a mockito mock itself be wrapped at runtime?

If I wrap a mock created by Mockito at runtime and then call a method on the wrapper, the wrapped mock is not called. Please, see below:
This is the test I run:
import static org.mockito.Mockito.verify;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;
import org.junit.Test;
import org.mockito.Mockito;
public class MyTest {
#Test
public void mockIsCalled() {
final Bar bar = Mockito.mock(Bar.class);
final Bar wrapper = wrap(bar);
wrapper.foo();
verify(bar).foo();
}
#SuppressWarnings("unchecked")
private <T> T wrap(final T objToWrap) {
return (T) Enhancer.create(objToWrap.getClass(), NoOp.INSTANCE);
}
}
where Bar is:
public interface Bar {
String foo();
}
The test fails and the output I get is:
java.lang.NoSuchMethodError: java.lang.Object.foo()Ljava/lang/String;
at Bar$$EnhancerByMockitoWithCGLIB$$d2b59df8.foo(<generated>)
at MyTest.mockIsCalled(MyTest.java:18)
...
If I turn Bar into a class as in:
public class Bar {
public String foo() {
System.out.println("foo");
return null;
}
}
the test continues to fail, foo is printed on the console, and I get the output:
Wanted but not invoked:
bar.foo();
-> at MyTest.mockIsCalled(MyTest.java:20)
Actually, there were zero interactions with this mock.
at MyTest.mockIsCalled(MyTest.java:20)
...
I am confused.
The real problem that I am trying to solve is to wrap dynamic proxies (injected by Mule via component binding) in order to memoize the method calls on the wrapped dynamic proxies. I want to make it generic enough so that it is sufficient to wrap the dynamic proxy object without having to extend any interface.
Thanks
The problem you're seeing in the case of the Bar class, you would also be seeing in the interface version, if not for the cglib wackiness. You're not wrapping the mock, you're creating a new object. So, the original mock is never exercised.
For using the class version, have you tried the version of create() that accepts interfaces as params?
I'm not sure I fully grok your usage scenario, but for something Mockito-specific, you could try taking the proxy created by cglib and then using spy() on that instead of mocking a fresh object.
I don't know much about cglib, frankly, but perhaps you could implement your own Callback, which contains and delegates to the original object. You could supply that Callback to Enhancer.create() instead of the NoOp one.

Resources