Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
The reasons I am dissatisfied with assert keyword in Java are
1) it's disabled by default, so it is a headache to make sure it's enabled when I want it to be
2) its behavior is rather rigid (I would want some inversion of control, ideally); but that's not terribly important.
Some of the alternatives I can think about:
JUnit's assertEquals() and such - good for tests, but can't use in main code
Guava's preconditions - great, but no assertion methods per se.
My own assertion library - I wrote it back in 1999, and back at the time it was great, but now I want to standardize.
Anything else?
So.. to sum it up.. how do I assert in production code in a way that is not disabled by default?
(And yes, this may be considered an anti-pattern by some, but I do want at least some assertions in Production, even if assertion failures are just silently logged. I see some room for that even in shrink-wraps, and definitely in websites).
I'd use Spring's Assert class, it includes a fairly extensive range of checks.
I am not sure if this is what you want, but I'm routinely using commons-lang Validate for many years already. Usually in public API methods/constructors to ensure that arguments are passed correctly. Not just notNull (see Lombok's #NotNull for this) but also noNullElements etc.
I especially like the <T> T notNull(T object) signature for immutables:
private final JSCodeModel codeModel;
private final String name;
public FunctionDeclarationImpl(JSCodeModel codeModel, String name,
String[] parameterNames, JSSourceElement[] sourceElements) {
this.codeModel = Validate.notNull(codeModel);
this.name = Validate.notNull(name);
...
}
What are your requirements, actually?
JUnit's assertEquals() and such - good for tests, but can't use in main code
Nothing technically prevents you from using JUnit assetions (and/or Hamcrest matchers) in your main code. Just include the Junit jar in your classpath. It's usually not done but that's more of a convention than any technical limitation.
Java 7 also introduced Objects.requireNotNull(obj, message) and similar methods although not as full featured as JUnit assertions.
but I think if you want to go with a more standardized approach Guava's preconditions is probably best.
Related
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 months ago.
Improve this question
I want to migrate old Java code to Java 17. Is it a good idea to replace:
Collections.unmodifiableList(Arrays.asList(....)); to List.of("....");
Should I expect code execution error or there should be no impact?
specific answer
Obviously, the best way to figure this out is to try it yourself.
If you want some certainty before you attack this challenge, it is usually a good idea to look at the method signatures in the java API documentation for the different versions.
Java 7 spec of Collections.unmodifiableList: https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#unmodifiableList(java.util.List)
Java 17 spec of List.of: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html#of()
As you can see, both return an unmodifiable List<E>. So I would say your update is quite safe.
general approach
In general, if you are going to refactor a common part of your codebase, it is a good practice to first extract all occurrences of this construct in your codebase onto a utility method.
For your case, you could create a simple utility class, like so:
public final class ListUtilWrapper {
public static <E> List<E> listOf(E... elements) {
return Collections.unmodifiableList(Arrays.asList(elements));
}
}
After each call is replaced by ListUtilWrapper.listOf(....), you compile and test your code.
Next up, you replace the implementation of ListUtilWrapper.listOf to be List.of(elements) and rebuild your codebase.
If all works well: inline the utility method after some manual testing. If it fails, you can easily roll back to a stable state.
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 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.
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 4 years ago.
Improve this question
MyClassBuilder myClassBuilder = myClassBuilder()
A factory method to return a builder, assigned to a local of the same name as the method.
I've never seen this before today. Does it make sense or should it be avoided? It's not possible to meaningfully do this in Python or C++, so as I'm new to Java it feels wrong. IntelliJ doesn't give so much as a warning and it results in some (to me) confusing looking code.
Put simply: Is this considered idiomatic Java?
Edit: I don't feel this is purely opinion based. Major players in the Java community (possibly even the language creators themselves) may or may not be using this 'feature' of the language. If they did it would indicate that it's idiomatic. Answers would ideally cite references to where it's being used or specific problems that it solves. I don't think this is a good language feature, I've never used it but I'm open-minded and prepared to be convinced otherwise.
In java method and field names have their own name spaces, so they can be given the same name.
There are some code styles, that might use it:
public class Human {
private String opinion;
public Human opinion(String opinion) {
this.opinion = opinion;
return this;
}
public String opinion() {
return opinion;
}
Repetition due to field/method, field/parameter and method overloading.
Seen in fluent APIs, Builder patterns, from time to time getter-setter haters.
As you can see from the above it is kind of repetitive too. Verbal phrases for method names seems better (except we have size() and such).
Possible, but...
It is possible, and will compile, but it is really confusing. I think it is better to avoid such naming for your coworkers and/or your future self.
You can see this website for good practices, and I think you can even find better, official sources.
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.