ArgumentMatchers.matches( String regex ) exists... and it is possible to devise regexes which don't match a given String. But it is far from trivial (several threads in SO).
Is it wrong of me (or wrong-headed) to think it might be a nice idea to request the Mockito designers to take the heavy-lifting out of this and add it as a feature? It just seems that, in the context of mocking and so forth, it is a far-from-exceptional use case...
PS also, I'm not clear with ArgumentMatchers.matches how you go about saying "this may be a multiline String we're matching against, don't worry about it"... wouldn't it be better to have a Pattern rather than a simple String?
later
Feature request "enhanced" at Mockito HQ (on Github). "bric3" there says one should use Jeff Bowman's technique for "does not match". But she/he seems to think the Pattern idea is worth thinking about.
Re not(): Mockito's own documentation says "Use additional matchers very judiciously because they may impact readability of a test. It is recommended to use matchers from Matchers and keep stubbing and verification simple."
Also I find I must "possible dupe" my own question: How to write a matcher that is not equal to something. Searching with hindsight is always easier...!
later still
Many thanks to Brice for adding this so quickly. Updated my gradle.build and... new 4.1 core downloaded from Maven Central and immediately available for use.
No need for a request: You can compose what you want using AdditionalMatchers.not.
when(yourComponent.acceptString(not(matches("foo|ba[rz]"))))
.thenThrow(new IllegalArgumentException());
If you want to match a Pattern, you might need to write your own ArgumentMatcher subclass, but it's quite easy from there:
public class MatchesPattern implements ArgumentMatcher<String> {
private final Pattern pattern;
public MatchesPattern(Pattern pattern) { this.pattern = pattern; }
#Override public boolean matches(String string) {
return pattern.matcher(string).matches();
}
#Override public String toString() {
return "[string matching /" + pattern.toString() + "/]";
}
/** Optional. */
public static MatchesPattern matchesPattern(Pattern pattern) {
return new MatchesPattern(pattern);
}
}
You can then consume that class using:
when(yourComponent.acceptString(not(argThat(new MatchesPattern(yourPattern)))
.thenThrow(new IllegalArgumentException());
// or with the static factory method:
when(yourComponent.acceptString(not(argThat(matchesPattern(yourPattern)))
.thenThrow(new IllegalArgumentException());
For future readers, Mockito 2.4.1 has been released with support of the Pattern class :
Now you should be abble to write :
when(yourComponent.acceptString(not(matches(Pattern.compile(...)))
.thenThrow(new IllegalArgumentException());
Related
I wanted to write a logic for matcher like matcher_1 AND matcher_2 OR matcher_3 and matcher_4 where matcher_i are just placeholder for hamcrest matchers.
I decided to write it using CombinableMatcher like this -
new CombinableMatcher<String>(matcher_1).and(matcher_2).or(matcher_3).and(matcher_4)
Now, the question is in which order matchers will be evaluated ?
Will it be ((((matcher_1) AND matcher_2) OR matcher_3) and matcher_4) or
any other order like ((matcher_1 AND matcher_2) OR (matcher_3 and matcher_4)) ?
Matcher results will be evaluated from left to right. So, it will be ((((matcher_1) AND matcher_2) OR matcher_3) and matcher_4) and not ((matcher_1 AND matcher_2) OR (matcher_3 and matcher_4)).
Following example ran in mockito 3.11 and hamcrest 2.2 proves the above -
#RunWith(MockitoJUnitRunner.class)
public class SomeTest {
#Mock
SomeInterface mock;
#Test
public void test(){
when(mock.complicatedMethod(eq(1), MockitoHamcrest.argThat(
new CombinableMatcher<String>(equalTo("hello"))
.and(containsString("ello"))
.or(CoreMatchers.<String>instanceOf(String.class))
.and(containsString("XYZ"))
) )).thenReturn("done");
System.out.println(mock.complicatedMethod(1 ,"hello"));// Prints null
}
}
interface SomeInterface {
public String complicatedMethod(int i , String str) ;
}
If matcher results which were evaluated in this order ((matcher_1 AND matcher_2) OR (matcher_3 and matcher_4)) [Which is by the way Java precedence order for boolean operator], then "done" would have been printed but it fails and null is printed which means ((((matcher_1) AND matcher_2) OR matcher_3) and matcher_4) is what it is considering.
Good to see that someone understands the idea of composing matchers.
I'm wondering why you're concerned with the ordering of matchers? Ideally it shouldn't matter, since you also don't know how often a matcher will be called.
If you have issues at this level of detail, it might be best to write a custom matcher.
I have an object that I want to serialize using Protocol Buffers and store in redis. The object contains a java.util.regex.Pattern that is complied when the object is instantiated.
public class SerializableEntity {
private Pattern pattern;
private List<String> options;
}
This pattern is used to validate inputs to a certain api. Since compiling the pattern each time is expensive, I'm compiling the pattern once during instantiation and then reusing the same pattern instance each time the api is invoked. How do I serialize this compile Pattern field in the following schema so I when I de-serialize the object, I can use it without compiling the pattern again?
message SerializableEntityProto {
repeated string option = 1;
// compiled pattern
}
Thanks.
java.util.regex.Pattern does not have encode and decode proto functions implemented in itself. However, you can implement that yourself pretty easy (as Andy Turner suggests). Something like this:
Proto
syntax = "proto2";
package termin4t0r;
option java_package = "com.example.termin4t0r";
// Proto for java.util.regex.Pattern
message RegexPatternProto {
// See Pattern.pattern()
optional string pattern = 1;
// See Pattern.flags()
optional int64 flags = 2;
}
Java encode and decode functions
class RegexpPatternProtos {
public static RegexPatternProto encode(java.util.regex.Pattern pattern) {
return RegexPatternProto.newBuilder()
.setPattern(pattern.pattern())
.setFlags(pattern.flags())
.build();
}
public static java.util.regex.Pattern decode(RegexPatternProto patternProto) {
return new RegexPatternProto(
patternProto.getPattern(), patternProto.getFlags());
}
}
I leave the unittests as an exercise :) I even find serializing this way preferable as protocol buffers have forward and backward compatibility, whereas java serialization has problems with that.
I think this is a case of square peg and round hole, protobuf and serialization is not meant to be used that way.
Anyway it seems like you initialize a regex with every API call. I don't know how your app decides which Regex to use for a particular API, but you must start out with a Regex string to compile.
Instead of trying to serializing the pattern, store it in memory in a HashMap<String,Pattern>( Regex string as a key and the compiled pattern as value). And then get the pattern when you need it.
I am a new Junit Learner I would like to test my code according to 2 list class. However I never saw any example of that.
My real code is below :
public static List<JourneyType> applyFilter(List<JourneyType> journeyList, List<AvailabilityFilterOptionType> filterOptions)
{
List<JourneyType> filteredJourneyList = new ArrayList<>();
filteredJourneyList = applyStopFilters(journeyList, filterOptions);
filteredJourneyList = applyCarrierFilters(filteredJourneyList, filterOptions);
filteredJourneyList = applyRbdFilters(filteredJourneyList, filterOptions);
filteredJourneyList = applyDurationFilter(filteredJourneyList, filterOptions);
return filteredJourneyList;
}
and my test scenario :
#Test
public void testApplyFilter()
{
fail("Not yet implemented");
}
Thank you in advanced
Actually, this is pretty simple.
#Test
public void testApplyFilter()
{
assertThat(someObject.applyFilter(journies, filters), is(expectedOutcome));
}
In other words: you know what this method is supposed to do. ( Well, such knowledge is the prerequisite for testing stuff. When you don't know what your code is doing, there is no point in verifying its correctness via testing...)
As in: given some known input data, you should be able put down an expectation about output coming back. And that is what you check for.
Of course, the tricky part could be to correctly identify dependencies, and mock them where needed.
But ideally, your test should just be that: testing the public contract of your method under test. Something goes in, and you check that the output coming back meets your expectations. Ideally, you have to mock nothing for such tests, because you do not at all rely on testing implementation details. You only test the public contract "given this input, this is the expected output".
( where: assertThat() is just a different type of assert, and is() is a hamcrest matcher. There are many other hamcrest matchers, such as containsInAnyOrder() (that one is really neat if you don't care about the order of elements returned, but one has to understand that is used slightly different, it would need containsInAnyOrder(expectedOutcomeList.toArray()) methinks )
Most of the methods in my application are written like this:
public void m() {
long t1 = System.currentTimeMillis();
log.info("begin - m()");
/* method body */
long t2 = System.currentTimeMillis();
log.info("end - m(), took " + (t2 - t1) + "ms.");
}
I wish I could simply annotate my method and have the log statements be automagically generated instead:
#Log("executionTime")
public void m() {
/* method body */
}
Any ideas on how to proceed with this approach ? Is there any known solution ?
Someone suggested AOP for this. The problem is that with AspectJ or Spring AOP I would have to describe all the methods which ammounts to as much code as the log calls in the method itself.
AspectJ and Spring AOP support something like:
execution(* com.company.project..*.*(..))
which will cover all methods in all sub-packages of project. So no need to define all methods one by one.
As has been suggested to you, AOP fits well to serve this requirement. Not sure what you meant by "having to describe all methods". From what I know there are ways to use wildcards to specify methods to which aspects apply, which could ease your work of "describing"..this is true at least in the case of Spring AOP..not sure about others.
And yes, CGLIB suggested by Maurice is another good candidate for your consideration. Never used it though.
CGLIB let you modify method code at runtime
AspectJ has the concept of a join point, which is like a wildcard that can specify any methods that match that wildcard (you can specify particular methods in a class or any class that matches the wildcard). Then you can create an aspect which contains before advice and after advice, which are methods that run before and after the method matched by the join point. You can generate your log methods this way.
Perf4j supports getting timing information for methods using annotations. See here in their developer guide.
While this is not an actual practical answer to your question just yet (some good answers have been with respect to AOP), I believe the concept of ARM in Java 7 should be a viable option for implementing something like this on a small scale.
You could define a utility logging class and a factory to produce that class, something like the following:
public class TimerFactory
{
private static final Logger log = ...; // Obtain however
static class Timer implements Disposable<RuntimeException>
{
private final long startTime;
private final String name;
private Timer(String name)
{
this.name = name;
startTime= System.currentTimeMillis();
log.info("begin - " + name);
}
public void close()
{
final long t2 = System.currentTimeMillis();
log.info("end - " + name + ", took " + (t2 - t1) + "ms.");
}
}
public static Timer getTimer(String name)
{
return new Timer(name);
}
}
Now with that boilerplate out of the way (essentially an encapsulation of your logging behaviour), it could be called as follows:
public void m() {
try (TimerFactory.getTimer("m()")) {
/* method body */
}
}
The first log method would be called at the entrance to the try block, and the start time recorded. When the try block was exited, the resource (the Timer in this case) would automatically be "closed", which would cause the final time to be calculated and logged. Note as well that because this is a try block, the end logging will happen regardless of whether an exception is thrown or not. Your original code should probably use a try-finally block to ensure that the logging is actually completed.
Obviously this still requires you to put some logging code at each site, so is not really a replacement for clever pointcuts and AOP, even once Java 7 is released. However, if you find yourself dropping the logging in every now and then into perhaps a handful of methods, this pattern is a good way to abstract out the logging concerns and allow you to reuse it with the minimum of boilerplate.
You should use an aspect to this requirement. This requirement is a crosscuting concern (a concern that "cuts" between many classes).
To capture the methods that you want match you should create a pointcut that matches one or more join points. A join point is something that can be executed on your code (a method for example).
Look at this simple examples about tracing and logging and at this link about wildcards and pointcuts.
Try #Loggable annotation from jcabi-aspects (powered by AspectJ):
#Loggable(Loggable.DEBUG)
public String load(URL url) {
return url.openConnection().getContent();
}
It logs through SLF4J, which you can redirect to your own logging facility like, say, log4j.
Comment out the logging or profiling calls with a unique search term:
void myfunc() {
//log-call-123: try { long log_t1 = System.currentTimeMillis();
//log-call-123: log.info("begin - myfunc()"); {
...
normal method code
...
//log-call-123: } } finally { long log_t2 = System.currentTimeMillis();
//log-call-123: log.info("end - myfunc(), took " + (log_t2 - log_t1) + "ms."); }
}
When you search and replace:
Search for: "//log-call-123:"
Replace with: "/* log-call-123 */"
Do the reverse search and replace when you want to turn off extra logging or profiling calls.
Like many log4j users, we often have debug level logging that is expensive to evaluate. So we guard those cases with code like:
if( _logger.isDebugEnabled )
_logger.debug("Interesting, my foojes are goofed up: " + getFullDetails())
However, that is uglier than a plain _logger.debug call, and sometimes the programmer doesn't realize the evaluation could be expensive.
It seems like it should be fairly simple to write a program that takes a compiled jar and guards all the _logger.debug calls with the isDebugEnabled check. We would likely be willing to accept the extra overhead of checking isDebugEnabled in all cases.
Has anyone tried this approach, or done similar post-processing of a jar?
Rather than looking at modifying the jar, I'd search for a solution using Bytecode Instrumentation. The problem will be to identify those parts of the code you want to wrap inside a .isDebugEnabled() - you will have to identify objects that are only used for log4j invocations.
Have you looked at AspectJ ? This supports aspects using bytecode weaving, and can interceptions into a previously compiled .jar file.
I believe a good solution would be that the code would be efficient as is.
Consider that log4j is deprecated. Its author itself left it as is, to avoid breaking compatibility, but he created a new one, SLF4J (http://www.slf4j.org/ ). He provides both a facade and an implementation, according to the distinction commons-logging/log4j, but without the flaws of each...
I believe that, in this new logging facility, you can send Object parameters to the logging, and that the level is evaluated before converting the Objects (to String or otherwise). The idea is to use a format string, and parameters.
Our code doesn't use slf4j, but we have utility methods that do exactly that.
It is coded roughly as follow (from memory):
public enum LogLevel {
FATAL, ERROR, WARNING, INFO, DEBUG;
public void log(Logger logger, String format, Object... parameters) {
if (isEnabled(logger)) {
logImpl(logger, String.format(format, parameters));
}
}
public boolean isEnabled(Logger logger) {
switch(this) {
case WARNING : return logger.isWarningEnabled();
case INFO : return logger.isInfoEnabled();
case DEBUG : return logger.isDebugEnabled();
default: return true;
}
}
private void logImpl(Logger logger, String message) {
switch(this) {
case WARNING : logger.warn(message);
// other cases
}
}
}
It is used as:
public void myMethod(Object param) {
LogLevel.WARNING.log(LOGGER, "What is my message ....", "myMethod", param);
}
UPDATE : If you need to call a method in the log...
One possibility is to use toString method. This is appropriate if your logging is 'technical', and will be used also when debugging.
If your logging is more functional (not targeted to the developper), I suggest to define an interface (it is functionally sound in that case, so it is useful to provide meaning) :
public interface Detailable { // the name could also suggest logging?
String getFullDetails();
}
Implement that interface in any object that need to be passed as logging object, with a complex calculation to build the log.