Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Lets say we have a pure java method. Its a simple validation method. It validates if the input is correct, and throws an exception if not.
static void validateInputIsOk(String input) throws InvalidArgumentException {
if (input == null || !input.equals("Valid input")) {
throw new InvalidArgumentException(new String[]{"Bad input"});
}
}
Its pure, and its static, its small, and easy to reason about.
So i`ve been reading a lot about java static methods and a lot of people advises against this.
Mainly due to testability.
Now that part i fully get. Its not easy mocking a static method. If I use this validator inside some other unit, then I must either accept it will be a part of the test (which could be ok since its pure), or use some sort of static mock framework.
But in order to make it mockable, and non static, I would have to sacrifice the simplicity and readability of my code. I would have to deal with creating the object, and possibly passing it as a parameter to the unit using it.
So in this light I would favour making my pure methods static, and not bother mocking them. It seems the to keep my code most simple and clean.
Would you think im right? Is it something im missing here?
I would argue that you only should mock methods that are public. I would also argue, that you only should test methods that are public. If your tests get too big this way, you should consider splitting up your implementation into more public classes, not necessarily make them non static.
Methods that have no side-effects, the term is functions, should be static. And are good style. Math offers many such functions.
For testing, one would not mock these functions, but test them in isolation.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 months ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
It occurred to me that interfaces cannot be instantiated and hence I could create an interface containing only a bunch of static utilities methods that I need as opposed to a regular class with a private constructor and public static methods. Any comments on that? Should I do it or does it not really matter?
A program is not just a set of instructions for a computer to obey. It's also a message to future developers. You should use the statements in your program to indicate to other developers (or even yourself a few months into the future), what you intend for the computer to do.
That's why we give variables, methods and classes clear names. It's why we lay out our programs in certain expected ways. It's why we use indentation consistently, and why we have naming conventions.
One of those conventions is that if you have a bunch of static methods that need to be organised together, they should be organised into a class, not an interface. Whether or not it's technically possible to put all your methods into an interface is not the question you should be asking. What matters is how to communicate most efficiently what you're actually intending to do.
To that end, please don't set up your program in strange, innovative ways. You're just going to confuse and annoy people.
Although this is possible interfaces should be used
when it is important for disparate groups of programmers to agree to a "contract" that spells out how their software interacts. Each group should be able to write their code without any knowledge of how the other group's code is written. Generally speaking, interfaces are such contracts.
https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html
Interfaces should be defined as an abstract type used to specify the behavior of a class; therefore they're meant to be later implemented.
What you're trying to do is not completely wrong (interfaces can offer static methods), but it's definitely not what they were designed for. If you want to offer a set of static utilities from a common "place", you could declare a final class with a private constructor, in order to prevent its extension (with possible methods overriding), and avoid its instantiation. The Math class is a perfect example of this.
Alternatively, if you want to declare instances of said class, you could declare your class normally, then declare its methods as final (to prevent their overriding) and offer a public constructor or a factory method.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In general, Powermock allows us to mock/stub an static behavior or state. For example, we could mock an static method of utility class like public static String buildKeyFrom(...) {...} and override its behavior. Or even return our mock instance when target class tries to create an object using constructor of class new MyService(...)
Few examples of powermock API usage:
when(StorageKeyUtils.buildKey(id, group, suffixes)).thenReturn("my:group-test:an-id:suffix1")
whenNew(MyParser.class).withArguments(factory).thenReturn(parserMock)
And... it works, actually it helps to avoid refactoring to improve test-ability of our code. You have no more needs to extract static behavior into separate classes, no needs to introduce factories to instantiate new objects and so on.
But, Powermock also have disadvantages:
Complicated setup.
In fact, it's not just single whenSomething like in Mockito, besides this and replacement of test-runner, you also forced to use #PrepareForTest and PowerMock.mockStatic(..). Try to remember what classes to be described within the annotation and inside mockStatic, without checking of tests you implemented previously or documentation.
Sometimes it even works without mockStatic while you still trying to mock static methods.
Of course we could spend some time and investigate documentation to clarify all questions...
Bugs and glitches.
Sometimes it works, sometimes it doesn't. Examples:
Conflicts with coverage tools. Due conflicts with instrumenting of classes you may face loss of coverage of your code by test, for example - JaCoCo
Try to google for powermock mbeanserver... Why powermockito tries to abuse mbeanserver and forces us to mark our test-sets with #PowerMockIgnore? Since 2013. Bot sometimes it works OK without exclude, why? - idk
Unable to mock static method or constructor passed as lambda by reference, for example: ``
It simply encourages usage of static - ambassadors of OOP welcome to describe why we mustn't use static methods, etc
In general, I would say yes, we should avoid usage of Powermock. One doubtful case I see for it - you have no time for appropriate design of you code to make it testable enough without power-mockito (, but do you really need that quality of testing, if you don't have time for code-design?)
What do you think? Do you use Powermock on regular basis? Do you follow some rules while using Powermock on your project?
Typically, clean code won't need powermock for testing. Because clean code supports dependency injection, is loosely coupled and is easy to unit test so doesn't rely on static methods.
Legacy / dirty code on the other hand is riddled with static methods, is tightly coupled and doesn't support dependency injection. It's these legacy code bases where you'll need powermock for testing
I don't recommend PowerMock but life is not always as we would like to have, sometimes you come into project which, let's say, doesn't follow best programming practices, then PowerMock can be accepted in my opinion. Question is a bit too broad.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
The PMD started warn me about having the God Class after adding a small private method to an existing class.
I didn't find any clarification what types of methods are considered to be the reason of the code smell. It only says that it uses metrics to make a decision and such a class does too many things.
From my point of view we can have as many private methods as we want as long as we follow the Single Responsibility rule.
So I wanted to know whether my assumption is right or should I obey the PMD warning and make a refactoring. Thanks!
I think you named the crucial concept: the single responsibility principle. And as long as you keep this concept in mind (and you follow the other SOLID rules) you should be fine.
I rather find a high number of private methods could be a good thing - as you are hopefully upholding the single layer of abstraction principle!
Of course: when there are really too many private methods it might be worth looking if there are certain "sub aspects" worth moving into distinct classes of their own.
To complete the very good GhostCat answer, I would add that
the God object pattern doesn't apply only for methods or even public methods.
It's an anti-pattern where the object (or class as the issue comes from static members) knows too much (fields) and or does too much (methods).
So fields and methods (public as private) accumulation in a same class may contribute to make a class or an object a undesirable god.
From my point of view we can have as many private methods as we want
as long as we follow the Single Responsibility rule.
Single Responsibility principle for API is a really good thing.
But it doesn't mean that private processing/fields should violate this one.
Indeed as a class becomes really "big", the cohesion between its members may become low and so an undesirable coupling between some members may appear.
So separating distinct processings in other classes makes sense to improve code readability and maintainability .
The point is that when you see that your class has too many private methods, often times this functionality can be extracted to another class and by doing so you can:
reduce duplication in your code base
improve its testability
So this rule is legitimate, because even if you think that your design is SOLID enough, many times your object composition could be in fact more crystalic.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
When a function gets even moderately large, I generally change it to become static. For example, if a classes toString() gets pretty big, I usually change it to
public String toString() {
return ClassName.toString(this);
}
private static final String toString(ClassName c_n) {
//.........
}
If the function is not excessively large, is it overkill to do this?
EDIT
I'm getting shot down big time here. :)
I understand how the static modifier should be used in general (for singletons, for stuff unrelated to a specific instance, for utility functions). I'm asking this from an optimization point of view: To avoid a large function's byte code from being duplicated in memory, for each instance of a class. I'm obviously wrong about how it works.
Making the function static depending on the length of the function is totally wrong. Static variables/method are belong to class, not to instances.
So, if there are common functionality between the instances, not depending on any instances, then they can be static.
Here, you have made the toString() as static. But, this method should be describe an instance. Making this as static will give error prone results.
Does it make sense to call this method, even if no object has been constructed yet?" If so, it should definitely be static. Otherwise, that should be instance method
You should make a method static if it doesn't depends of an instance of the class where it is declared. It has nothing to do with the length of the function.
Code (methods) is not replicated per instance, it doesn't need to as it is the same for all instances and is not modified.
Only instance data (properties) is replicated.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I'm asking this question because I believe they did it for a very good reason and that most people do not use it properly, well from my experience in industry so far anyway. But if my theory is true then I'm not sure why they included the private access modifier...?
I believe that if default access is properly used it provides enhanced testability whilst maintaining encapsulation. And it also renders the private access modifier redundant.
The default access modifier can be used to provide the same affect by using a unique package for methods that need to be hidden from the rest of the world, and it does this without compromising testability, as packages in a test folder, with the same are able to access all the default methods declared in a source folder.
I believe this is why Java uses package access as 'default'. But I'm not sure why they also included private access, I'm sure there is a valid use case...
I agree about using the default (package private) modifier for stuff that is to be accessed by tests, but I don't agree about private being unnecessary. Even for tests there is a lot of stuff that is not needed to be visible.
For a good test, implementation details are unnecessary and should not be visible outside the class. The more "whitebox" a test is, the more fragile it is. I usually limit the default modifier to fields I expect to be set via dependency injection and set manually in a test. (I could also use constructor injection and get rid of this, but this is more convenient.)
I propose little thought-experiment. Consider this code:
public void promoteUser(User user)
{
int newRank = computeNew(user);
user.setRank(newRank);
}
private int computeNewRank(User user)
{
return user.getRank() + 1;
}
One might feel computeNewRank should be tested (real implementation might do lot more stuff). But let's forget that for a moment and through the magic of inlining do this:
public void promoteUser(User user)
{
int newRank = user.getRank() + 1;
user.setRank(newRank);
}
The beauty of this experiment is that it applies to private methods of any size. You can always imagine yourself inlining private member and asking yourself "What do I really want to test here?". Is it the private method itself or perhaps new class/component with brand new functionality that's disguised as private method? The point is, you should rarely (if ever!) need to test private (or even package/internal) members. To outside world, to your contract consumers those are all irrelevant details.
Now, of course we could replace everything with system tests. But then how your regular work flow would look like? What if in order to test the rank promotion code you'd have to log user, register for session, wait 3 minutes, enter promotional code, receive sms, confirm... You see my point.
It's good to remember that unit tests are for you, not the other way around. You can bend them, adjust them, make them fit so that you can deliver software of better quality. Thier purpose is not to help you achieve some magical goal of 100% coverage, but rather to give you immediate feedback on what you're doing so that you can react more quickly to bugs and failures you will encounter. Or in other words, to improve your productivity.