Is it possible to mock a Java protocol buffer message? - java

Protocol buffer classes are marked final, presumably for efficiency; however, this makes them quite difficult to test with -- Mockito can't mock/spy on final classes. I've tried using PowerMockito with no success: I get a ClassFormatError when preparing the final class for the test.
My solution up until now is to create mockable adapter interfaces, but I'm hoping there's a less laborious approach.

JMockit can handle final and static. Just pay attention to how to set it up as it requires the -javaagent JVM parameter, or classpath tweaks, or extra annotations to be able to mock final and static stuffs.

JDave has an Unfinalizer that integrates with the JMock ClassImposteriser
It can't unfinalize classes loaded from the the boot classloader, and it requires a VM argument when launching the tests.

Related

What is the difference between #TestOnly and #VisibleForTesting in unit test

As per my understanding, these annotations used for methods with an access modifier that allows method invocation from another class for unit testing
#VisibleForTesting - com.google.common.annotations.VisibleForTesting
#TestOnly - org.jetbrains.annotations.TestOnly
The first big difference is obviously that it's provided by different projects.
#VisibleForTesting is part of the Google Guava libraries and #TestOnly is part of JetBrains annotations which are associated with JetBrains, the makers of IntelliJ IDEA, among others.
Comparing the JavaDoc of the two shows that they serve basically identical goals: #TestOnly and #VisibleForTesting.
Note that the documentation of both annotations contain a note effectively warning you that the annotation itself does not prevent production code from calling the annotated method. JetBrains suggests the use of static checking tools that support that annotation (one of which is presumably built into IntelliJ IDEA) and Guava suggests the use of external checker tools with an explicit list of forbidden APIs.
tl;dr They indicate effectively the same thing. The decision which one to use depends mostly on which tools you are using to act on them and which one they support. Already using other annotations or classes from one of those packages is another reason to pick one over the other.
They are not for the same thing.
#VisibleForTesting is used for a methods that could be private/package-visible but has a higher visibility so it can be used by tests. Such a method can still be called in Production.
#TestOnly is used for a method that can only be used by tests, for instance to create a stub or to perform an additional validation only when testing. Such a method should never be called in Production, although the annotation won't prevent that.
By the way, JetBrains provide both annotations, so they can be used in the same project.

#Autowired variables access in Spock setupSpec()

I need to execute block of code once upon startup on the Spock tests. I cannot use #Autowired in setupSpec() which is default method for such initialisation, however #Beans would not be loaded till that time.
Found on web (dating back to 2015) source :
The behavior is a consequence of the design of Spring's TestContext framework. I don't
see a way to change it without hitting other problems. The situation isn't any different
when using the TestContext framework with JUnit.
It's been 6 years already, is there any clean way to do this? I want to omit dirty workarounds
You are in luck, thanks to #erdi for implementing this in Add support for injection into #Shared fields in spock-spring module, you can try the feature in the Spock Snapshot 2.0 builds, and it will be in the Spock-2.0M5 release. You need to opt-in into #Shared injection via placing #EnableSharedInjection on your specification, also really important, that you read the javadoc and understand the mentioned implications of doing that.

Can PowerMock be used without annotations?

I'm trying to use PowerMock as a library in another application. Is there a way to use it to mock a static method call without using annotations (I'm in Clojure which doesn't really do annotations)
According to powermock support and this blog, I guess there is no way to avoid annotations in test. I guess we need the #PrepareForTest(StaticClass.class) however. So I believe it is not possible to avoid #PrepareForTest atleast. May be I am wrong, but just thought of sharing what I found.
In fact, it's possible, although the way to final solution is painful.
PowerMock runner just initializes test environment in different classloader, in which the classes specified in PrepareForTest annotation are tweaked by Javassist. So assumed you mimic the work of the classloader and call Javassist by yourself, you can achieve the same effect.
As an example, I utilized PowerMock (internals without annotations) to discover name of method for given method reference. Further info can be found on my blog (in Czech, with working examples). I emphasize such an usage is only experimental and not suitable for production usage.

Mocking static methods in Java without annotations

Are there any libraries for the JVM that allow mocking of static methods WITHOUT needing annotations? I am attempting to build this feature into a Clojure testing framework (Midje). Clojure has very poor, or non-existant annotation support.
Use powermock.It's a great library for mocking. And here is an example that explains how to mock static methods.

Use Javassist in JUnit test

I have quite shallow understanding of JUnit and Javassist, i just want to use them to do some program analysis. For example given a library, I want to know during the runtime what methods in the library have been invoked. I can use bytecode manipulation to insert a system.out.println("method_name"); statement in the beginning of a method. So during the runtime, it will print out what methods have been invoked.
In standalone application i can intercept before the main() is called and use my own class loader(see below), however in JUnit there is no main(), could anyone show me how to intercept at this situation?
Many thanks.
...
Loader loader = new Loader( pool );
loader.addTranslator( pool, xlat );
loader.run( className, args );
...
Edit: I use JUnit 4.8 and Javassist 3.15.0.GA
Might I recommend an alternative approach instead? You can use an aspect-oriented approach instead, using AspectJ. With that, you can define pointcuts around a subset of or all methods that you want to monitor.
Another option is, if you're looking to monitor code coverage (the fact that you're using JUnit and just looking to do System.out.println(...) are good hints of this), maybe you're looking for a code coverage tool? If so, Cobertura would be your best bet - with no custom coding required.
Both of these options do their own byte-code manipulation, but without being something that needs to be maintained by the developer.
If you're using Eclipse as your IDE, both of these tie-in very nicely to Eclipse. AspectJ is actually an Eclipse project, but doesn't require Eclipse. The Eclipse plug-in for Cobertura is eCobertura.
Yet another option for this is to do it within JUnit itself - and this wouldn't require any bytecode manipulation. Take a look at its TestWatchman class. I don't yet have this documented online as I do with my other libraries, but you could take a look at my BaseTest class as part of my JUnit utilities library. Any JUnit test class that extends this will automatically log (to SLF4J) when each test starts, succeeds, or fails. However, this is all at a test-level only, and won't help monitor other methods that each test runs.

Categories

Resources