Good practice: Keeping local variable scope VS dependency injection - java

Good practices dictate that variables should be declared as local as possible. This however, is getting in the way of the good practices of dependency injection for the sake of unit testing.
Example:
Class A {
public A() {}
public void start() {
Map<Integer, VirtualMachine> vms = VirtualMachine.getAllVMs();
// more code here
}
}
Now I can't unit test the start() method. (getAllVMs() happens to be a static method in this case, but it could've just as easily been a new object. note: I don't want to use powermock).
So what I can do is use google guice to inject it, but if I do that, I need to give vms class scope, even if I am only using it locally in that method.
Is there a way around this or am I forced to make it a class field?
Thanks

If that variable's value is needed only in the single method call, then pass it as a method parameter. If it applies across a number of independent method calls, providing a common context, then the logical scope is "larger" than the method, and it should be a field.

Related

Java: [Global method access] enum with a single instance vs on-demand object construction vs static

I want to create a class with few methods which can be used anywhere inside a package. I opted to use enum with a single instance after reading that it automatically provides safe instantiation, serialization and protection from instantiating outside the enum. I believe it is the most easy and safe way of creating a singleton. But my superior came back saying that it's dirty programming. Is it really? Do anyone know the disadvantages of using an enum instead of object construction and passing around references using a class? When are enums initialized?
public enum Myenum {
INSTANCE;
public void init(...) {..initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
public class Myclass {
public Myclass(...) {...initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
public class Myclass {
public static void init(...) {...initialize local variables...}
public static method1 (...) {...}
public static method2 (...) {...}
}
In my view the disadvantage of using the second method is that an object reference of Myclass is needed everywhere I need to use methods and synchronization issues while object construction. I am not really using the serialization benefit of enum in my case.
Does enum implicitly provide the benefit of dependency injection? (i.e. Can access Myenum's method1, method2 everywhere inside the package without worrying about instance creation)
One other feature of enum I needed was methods inside an enum cannot be overriden outside of it.
Am I missing some obvious disadvantage here?
An enum gives a semantic signal to other programmers that it's a type with a series of possible values that you could check against, for example, in a switch statement. However, there are a number of compelling reasons why enums can be seen as a better implementation of a singleton pattern than most other patterns people typically use in Java.
If you're positive you want to use a singleton pattern, then using an enum is probably okay. However, there are patterns that tend to be more flexible, unit testable, SOLID, etc. What if one day you decide that you don't actually want this to be a singleton anymore? What if you want it to be refreshable when certain changes are made in the database? Using any singleton pattern is going to lock you into a singleton representation and make it harder to make changes like this in the future.
A Factory pattern would be more flexible than a singleton, but the best pattern of all, in my opinion, would be to use dependency injection. You can singleton-bind your type to avoid the costs of reinstantiating it, but the type itself (and its consumers) need not be tied to a specific lifetime or pattern.
Check out Java Concurrency In Practice and it's static singleton pattern. It looks like this:
public class ResourceFactory {
private static class ResourceHolder {
public static Resource resource = new Resource();
}
public static Resource getResource() {
return ResourceHolder.resource;
}
}
It's safe due to how/when statics are initialized, probably for the same reasons the Enums singleton trick is safe.
In JCIP's example, it's returning a thing, but you can add all the static methods you want that use however many variables you want to initialize in the ResourceHolder. And there's no init() call required.
I found an answer here to why creating a globally accessible pattern is bad instead of passing around references.
Excerpt:
They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.
They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.
They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.
They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

Extending a class with final attributes. Mockup

I usually set each attribute of a class as final (only for attributes that will be initialized within the constructor).
The point is that I am now implementing a Mockup of an object for testing purpose. This Mockup extends the class that it is mocking up and this class has some final attributes. Therefore I'm forced to call the super() constructor within the constructor of the Mockup object. This breaks however the utility of the Mockup because I don't want it to initialize all of the attributes in the way the normal class does it. I'd rather call the Mockup constructor without calling to super() and doing whatever I want.
My question is: Is it a good practice to define attributes as final as long as they will force you to call the class constructor in the Mockup?
EDIT: I add some code. The problem in this case is that I'm using a singleton, I know that this is not a good idea when testing but in this case I cannot change it. So my intention is not to call this method in the Mockup.
public class ReportsDataManager {
private final Map<String, List<String>> translations;
public ReportsDataManager() {
this.translations = GenericUtils.getTranslation();
}
}
Declaring attributes final is a very good practice when you can do it. It confers immutability - guaranteed thread safety. Breaking it to mock is a bad idea. Your design should serve the user's needs, not your testing convenience.
If you wish to mock the class, give it an interface and mock the interface. Also, mocks aren't stubs. It sounds like you're creating a stub, rather than a mock.
If you do wish to create a mock, pick a library that generates mocks for interfaces for you.
In general I'd say that if a practice you use makes testing your code more difficult then the practice may be a smell.
Try to decide exactly what you want to achieve by setting variables final. Would protected be acceptable?
You can sidestep the final restriction with standard reflection. Since you are in the context of a mockup, this wouldn't cause much problems, I suppose. Just beware of multithreading issues: the JVM will assume the field adheres to the final semantics and will optimize with that in mind.

Why is using static helper methods in Java bad?

I'm asking because I'm trying to use a mocking framework (Mockito) which does not allow you to mock static methods. Looking into it I've found quite a few blog posts saying that you should have as few static methods as possible, but I'm having difficulty wrapping my head around why. Specifically why methods that don't modify the global state and are basically helper methods. For instance I have a class called ApiCaller that has several static methods. One of the static method's purpose is to execute an HTTP call, deal with any custom issues our server might have returned (ex. user not logged in) and return the response. To simplify, something like:
public class ApiCaller {
...
public static String makeHttpCall(Url url) {
// Performs logic to retrieve response and deal with custom server errors
...
return response;
}
}
To use this all I have to do is call ApiCaller.makeHttpCall(url)
Now I could easily make this a non static method like:
public class ApiCaller {
...
public String makeHttpCall(Url url) {
// Performs logic to retrieve response and deal with custom server errors
...
return response;
}
}
and then to use this method call new ApiCaller().makeHttpCall() but this just seems like extra overhead. Can anyone explain why this is bad and if there is a better solution to making the methods non static (other than just removing the keyword) so that I can stub out these methods using the mocking framework?
Thanks!
The problem with static methods is they're very hard to fake when they're not relevant to the system you're trying to test. Imagine this code:
public void systemUnderTest() {
Log.connectToDatabaseForAuditing();
doLogicYouWantToTest();
}
The connectToDatabaseForAuditing() method is static. You don't care what this method does for the test you want to write. But, to test this code now you need an available database.
If it were not static the code would look like this:
private Logger log; //instantiate in a setter AKA dependency injection/inversion of control
public void systemUnderTest() {
log.connectToDatabaseForAuditing();
doLogicYouWantToTest();
}
And your test would be trivial to write without a database now:
#Before
public void setUp() {
YourClass yourClass = new YourClass();
yourClass.setLog(new NoOpLogger());
}
//.. your tests
Imagine trying to do that when the method is static. I can't really think of a way except for modifying the logger to have a static variable called inTestMode that you set to true in the setUp() to make sure it doesn't connect to a database.
It is less modular. Instead you should define an interface ApiCaller with an instance method makeHttpCall() so that you can define separate implementations in the future.
In the very least you will always have 2 implementations of an interface, the original and the mocked version.
(Note: there are some mocking frameworks that allow you to mock static methods)
As an addendum, while this may not be the case in your specific application, typically the use of static methods is indicative of a larger design oversight. Designing for modularity and reuseability should be prevalent throughout your application, because even though you don't need it right now you may need it in the future, and it's much harder and much more time consuming to change things after the fact.
PRIVATE Static helper methods are not bad, in fact, they are actually preferred at the large corporation where I work. And I use Mockito with them all the time, accessed from the methods that call the static helper method.
There is a slight difference in how the compiler treats a static helper method. The byte code created will result in an invokestatic instruction, and if you remove the static the result will be one of the other instructions, like invokespecial. The difference there being that invokestatic loads the class to access the method, where invokespecial pops the object off the stack first. So there might be a slight performance advantage (maybe not).
That you can't mock them easily when you need to pretty much answers your own question.
Particularly when it's something as shown: making an HTTP call is expensive, and doing that for unit testing your code makes no sense–save that for integration testing.
Unit tests require known responses (and response codes) from HTTP calls, something that you can't do if you're calling someone else's service, using a network you don't control.
This explanation seems to me very straight forward, and easy to understand.
Declare utility methods as static, often makes your code easier to understand, which is a good thing.
But, there is a serious limitation to this approach though: such methods / classes can't be easily mocked.
So if a helper method has any external dependency (e.g. a DB) which makes it - thus its callers - hard to unit test, it is better to declare it non-static.
This allows dependency injection, thus making the method's callers easier to unit test.
Source: https://softwareengineering.stackexchange.com/a/111940/204271

Unit test for method that calls multiple other methods using Mockito

Perhaps I have completely fallen short in my search, but I cannot locate any documentation or discussions related to how to write a unit test for a Java class/method that in turn calls other non-private methods. Seemingly, Mockito takes the position that there is perhaps something wrong with the design (not truly OO) if a spy has to be used in order to test a method where mocking internal method calls is necessary. I'm not certain this is always true. But using a spy seems to be the only way to accomplish this. For example, why could you not have a "wrapper" style method that in turn relies on other methods for primitive functionality but additionally provides functionality, error handling, logging, or different branches dependent on results of the other methods, etc.?
So my question is two-fold:
Is it poorly designed and implemented code to have a method that internally calls other methods?
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
This might be a difficult request, but I would prefer for those who decide to answer to not merely re-publish the Mockito verbiage and/or stance on spies as I already am aware of that approach and ideology. Also, I've used Powermockito as well. To me, the issue here is that Mockito developed this framework where additional workarounds had to be created to support this need. So I suppose the question I am wanting an answer to is if spies are "bad", and Powermockito were not available, how is one supposed to unit test a method that calls other non-private methods?
Is it poorly designed and implemented code to have a method that internally calls other methods?
Not really. But I'd say that, in this situation, the method that calls the others should be tested as if the others where not already tested separately.
That is, it protects you from situations where your public methods stops calling the other ones without you noticing it.
Yes, it makes for (sometimes) a lot of test code. I believe that this is the point: the pain in writing the tests is a good clue that you might want to consider extracting those sub-methods into a separate class.
If I can live with those tests, then I consider that the sub-methods are not to be extracted yet.
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
I'd do something like that:
public class Blah {
public int publicMethod() {
return innerMethod();
}
int innerMethod() {
return 0;
}
}
public class BlahTest {
#Test
public void blah() throws Exception {
Blah spy = spy(new Blah());
doReturn(1).when(spy).innerMethod();
assertThat(spy.publicMethod()).isEqualTo(1);
}
}
To me, this question relates strongly to the concept of cohesion.
My answer would be:
It is ok to have methods (public) that call other methods (private) in a class, in fact very often that is what I think of as good code. There is a caveat to this however in that your class should still be strongly cohesive. To me that means the 'state' of your class should be well defined, and the methods (think behaviours) of your class should be involved in changing your classes state in predictable ways.
Is this the case with what you are trying to test? If not, you may be looking at one class when you should be looking at two (or more).
What are the state variables of the class you're trying to test?
You might find that after considering the answers to these types of questions, your code becomes much easier to test in the way you think it should be.
If you really need (or want) to avoid calling the lower-level methods again, you can stub them out instead of mocking them. For example, if method A calls B and C, you can do this:
MyClass classUnderTest = new MyClass() {
#Override
public boolean B() {return true;}
#Override
public int C() {return 0;}
};
doOtherCommonSetUp(classUnderTest);
String result = classUnderTest.A("whatever");
assertEquals("whatIWant", result);
I've used this quite a quite a bit with legacy code where extensive refactoring could easily lead to the software version of shipwright's disease: Isolate something difficult to test into a small method, and then stub that out.
But if the methods being called are fairly innocuous and don't requiring mocking, I just let them be called again without worrying that I am covering every path within them.
The real question should be:
What do I really want to test?
And actually the answer should be:
The behaviour of my object in response to outside changes
That is, depending on the way one can interact with your object, you want to test every possible single scenario in a single test. This way, you can make sure that your class reacts according to your expectations depending on the scenario you're providing your test with.
Is it poorly designed and implemented code to have a method that internally calls other methods?
Not really, and really not! These so called private methods that are called from public members are namely helper methods. It is totally correct to have helper methods!
Helper methods are there to help break some more complex behaviours into smaller pieces of reusable code from within the class itself. Only it knows how it should behave and return the state accordingly through the public members of your class.
It is unrare to see a class with helper methods and normally they are necessary to adopt an internal behaviour for which the class shouldn't react from the outside world.
What is the best practice and/or approach in writing a unit test for such a method (assuming it is itself a good idea) if one has chosen Mockito as their mocking framework?
In my humble opinion, you don't test those methods. They get tested when the public members are tested through the state that you expect out of your object upon a public member call. For example, using the MVP pattern, if you want to test user authentication, you shall not test every private methods, since private methods might as well call other public methods from an object on which depend the object under test and so forth. Instead, testing your view:
#TestFixture
public class TestView {
#Test
public void test() {
// arrange
string expected = "Invalid login or password";
string login = "SomeLogin";
string password = "SomePassword";
// act
viewUnderTest.Connect(login, password);
string actual = viewUnderTest.getErrorMessage;
// assert
assertEqual(expected, actual);
}
}
This test method describes the expected behaviour of your view once the, let's say, connectButton is clicked. If the ErrorMessage property doesn't contain the expected value, this means that either your view or presenter doesn't behave as expected. You might check whether the presenter subscribed to your view's Connect event, or if your presenter sets the right error message, etc.
The fact is that you never need to test whatever is going on in your private methods, as you shall adjust and bring corrections on debug, which in turn causes you to test the behaviour of your internal methods simultaneously, but no special test method should be written expressly for those helper method.

Java Style / Best Practice - passing fields to methods vs accessing directly

In Java, given the following class:
public class MyClass {
private final Dependency dependency;
public MyClass(Dependency dependency)
{
this.dependency = dependency;
}
public void doWork()
{
// validate dependency...
}
The doWork method needs to invoke a method that uses dependency.
Which of the following two variations is considered "best practice", and why?
// Access dependency directly
void validateDependency()
{
this.dependency.something();
}
// access dependency as passed to the method
void validateDependency(Dependency dependency)
{
dependency.something();
}
I find myself favouring the latter, passing the dependency directly to the method, as it makes the method easier to test in isolation (albeit, marginally).
However, I'm interested in the java convention / best practice here.
A class exists because you have state and operations that are coupled to that state. There's no good reason to pass part of that state as a parameter to a class method.
In fact, it would indicate to me that that piece of state should not actually belong to the class. Or that the method doesn't belong to the class.
Using a parameter "so that it's easier to unit test" is a good indication that the latter holds (the method should not be in the class).
Well, in your example you are asking the function to do something with Dependency which lends itself to a static function, not a member function.
My rule of thumb is: Use members directly when calling a method on an object that owns the member but pass references when doing/testing something directly related to the dependency and favor static methods for the latter
That a bit verbose but I hope it helps. As always try to "do the right thing" and differences this small won't likely make a huge impact on maintenance or readability of your code.
There isnt a right way to do it. I prefer just putting the variable there.
Dependency injection. The second option is "best".
If you make your "Dependency" class an interface it makes code more modular, easier to test, less coupled.

Categories

Resources