I wanted to create a custom JUnit annotation, something similar to expected tag in #Test, but I want to also check the annotation message.
Any hints how to do that, or maybe there is something ready?
JUnit 4.9 tightened up the library's use of "rules" for tests, which I think might work as well as a custom annotation. Take a look at TestRule as a starting point. You can implement a rule based on that interface, and then use either the #ClassRule or (method-level) #Rule annotations to put them into play in your tests.
A good concrete example is ExpectedException, which lets you specify exceptions like the expected parameter for #Test does (and then some).
To make JUnit4 pickup your custom annotations, you need to write your own custom Runner implementation, and then supply that to the RunWith-annotation on the Test class.
You can start out by having a look at the BlockJUnit4ClassRunner, which is the default implementation runner for JUnit 4 (if memory serves me well).
Assuming you would want to pick up a custom annotation named #MyTest with a custom runner MyRunner, your test class would look something like:
#RunWith(MyRunner.class)
class Tests {
...
#MyTest
public void assumeBehaviour() {
...
}
}
The answer by "Reid Mac" does a fairly good job at decribing how a custom annotation is implemented.
You can create custom TestRule as mentioned in first answer or you can use/extend TestWatcher that already have method for processing start/finish of test.
There is a method apply(Statement base, Description description) where description is actually a wrapper around your test method. Description has a great method getAnnotation(annotationClass) which will let you do what you want by specifying a custom annotation you want to process
Related
Let's say we have a project full of unit tests (thousands) and they all should look like this
#Test
public void testExceptionInBla() {
// some test
}
But in one case someone forgot to put an #Test decorator on top of the test.
What would be an easy way to spot those tests, without looking through all the code manually?
I want to find code like this, it's a test without #Test:
public void testExceptionInBla() {
// some test
}
I were you I would look at some Sonnar rule here I found something that may can match requirement:
https://rules.sonarsource.com/java/RSPEC-2187
But in one case someone forgot to put an #Test decorator on top of the
test.
And
I want to find code like this, it's a test without #Test:
public void testExceptionInBla() { // some test }
Annotating the method with #Test or specifying a test prefix in the method name is about the same thing in terms of consequences if the developer forgets to do that.
If the #Test is the way today, that is not chance.
The #Test annotation brings two real advantages on the test prefix :
1) it is checked at compile test. For example #Tast will provoke a compilation error while tastWhen...() will not.
2) #Test makes the test method name more straight readable : it allows to focus on the scenario with a functional language.
should_throw_exception_if_blabla() sounds more meaningful than test_should_throw_exception_if_blabla().
About your issue : how to ensure that tests are effectively executed, I would take things in another way. Generally you want to ensure that unit tests execution covers a minimum level of the application source code (while you can go down at package or class level if makes sense).
And that is the coverage tools goal (Jacoco for example) to do that job.
You can even add rules to make the build fail if the level of coverage of classes belonging to some package are not covered at least at a specified minimum level (look at that post).
Small Adding :
If you really ensure that methods of test are correctly annotated, you have a way :
1) you have to choose a convention for test methods : for example all instance and not private methods in a test class are test methods.
2) Create a Sonar rule that retrieves all non private instance methods of test classes and ensure that all these methods are annotated with #Test.
3) Add that rule to your Sonar rules.
I want to spy a class who has a custom Annotation, but when I try to get annotations it has not anything.
My class is defined as:
#FisaEntity(name="TCRB_AFL_AFFILIATION", applicationId="CRB_AFL_REQ", master=true)
#PrimaryKeyFields(names={"CRB-TCRB_AFL_AFFILIATION-AFFILIATION_ID", "CRB-TCRB_AFL_AFFILIATION-AFFIL_SEQ" })
public class Affiliation{
}
When I try to get the annotations with this code:
FisaEntity entityAnnotation = (FisaEntity)klass.getAnnotation(FisaEntity.class);
And my test run this:
Affiliation affiliation = spy(new Affiliation());
Debugging my code, I can see my variable klass is:
com.req.model.Affiliation$$EnhancerByMockitoWithCGLIB$$123#123
Do anyone know any hack?
You answered your question yourself:
com.req.model.Affiliation$$EnhancerByMockitoWithCGLIB$$123#123
Simply don't make any assumption on mocks or spies. Use them for what they are meant to be: "test stubs" that provide functionality (aka behavior) to you.
In other words: you create mocks so that you can control/verify method calls made on these objects. You somehow inject the mocks into your code under test to get to the effects you intend to cause/observe.
Anything beyond that, like "hoping" that the class created by Mockito to do its magic has all the same annotations and whatnot of the original class: simply not a good approach.
As said: you are mocking objects to control their behavior, not the structural composition of the corresponding class that Mockito has to generate in order to instantiate the mocked objects.
Class clazz = Affiliation.class;
Annotation[] annotations = clazz.getAnnotations();
Annotation annotation = clazz.getAnnotation(Component.class);
These both should give you all the annotations of the class and the particular annotation of the class.
From your question, it is not clear what klass is!
If the purpose of your testing is solely to test that the annotation exists, then this way you can get the annotation(s) and then assert them...
I understand that,
#Before and #BeforeClass run before each test, or the entire test class, respectively
#Rule and #ClassRule wraps each test, or the entire test class, respectively.
Let's say I need to initialize some data before each test method,
How do I decide between using #Before and #Rule? Under what conditions is one preferred over another? The same question also goes for #BeforeClass vs.#ClassRule.
In order to use #Rule, you require a class that implements TestRule(preferred) or MethodRule, as can be read here.
Whereas #Before and #After require a new method to be written in every test case, #Rule does not because it is only an instantiation of already existing code.
So, if you would use #Before and #After for setUp() and tearDown() that you'll be using in many test cases, it is actually a better idea to use #Rule because of code reuse. If you have a test case that requires a unique #Before and/or #After, then these annotations are preferable.
For a bit more elaborate answer with a couple examples, take a look here. Ajit explains it very well.
Indeed, as #Quwin suggested, accoridng to JUnit 4.12 API doc,
TestRule can do everything that could be done previously with
methods annotated with #Before, #After, #BeforeClass, or
#AfterClass, but TestRules are (1) more powerful, and (2) more easily shared
between projects and classes.
Ways that TestRules are more powerful:
There are known implementing classes of the TestRule, which are some usefuls rules you can use out-of-the-box,
For examples of how this can be useful, see these provided TestRules, or write your own:
ErrorCollector: collect multiple errors in one test method
ExpectedException: make flexible assertions about thrown exceptions
ExternalResource: start and stop a server, for example
TemporaryFolder: create fresh files, and delete after test
TestName: remember the test name for use during the method
TestWatcher: add logic at events during method execution
Timeout: cause test to fail after a set time
Verifier: fail test if object state ends up incorrect
Another benefit of rules, is that multiple rules can be used in a single test case. You may want to use RuleChain to specify the order in which the rules should be run.
I have a huge project with numerous test cases. Some test cases are suppose to work on only particular environments and some are not. So I'm trying to skip or disable tests which don't belong to that environment.
I'm using Annotation Transformers to override #Test 's behaviour.
Here is my Transformer code in
package com.raghu.listener
public class SkipTestsTransformer implements IAnnotationTransformer {
public void transform(ITestAnnotation annotation, Class testClass,
Constructor testConstructor, java.lang.reflect.Method testMethod){
// I intend to do this later
// if(someCondition){
// // Do something.
// }
System.out.println("Inside Transform");
}
}
As of now I'm just trying to print.
I have many packages and classes on which I have to impose this Transformer.
How and Where should I initiate this class?
Please suggest any better methods for doing the same.
Thanks in advance
IAnnotationTransformer is a listener. You do not need to instantiate it, testng would do it for you. You can specify a listener in any of the listed ways here., either through your xmls or through service loaders, depending upon your test environment.
If you do not have groups marked in your testcases, then I think this is the way to go by setting the enabled attribute to false. There is another way to skip a test in IInvokedMethodListener, but I do not see any benefit of one over the other.
I am wondering if I can use custom annotation to call some method right after annotated one. For example I have a class that holds some settings that can also notify objects that something has changed (for example user changed something in settings panel). Not all listeners are interested in all types of events, so MyEvent is enum. Now I have structure like this:
class Settings
{
private ArrayList<Listeners> listeners;
private void notifyListeners(MyEvent e)
{
// notify all listeners that something was changed
}
public void setSomeOption(int value)
{
// validate parameter, store it etc.
notifyListeners(MyEvent.SOME_INTEGER_SETTING_CHANGED);
}
}
Of course listening object has to check type of event and ignore it or perform some action, but it is not the case here.
I am interested if I can achieve this with annotations, like this
#NotifyAnnotation(MyEvent.SOME_INTEGER_SETTING_CHANGED)
public void setSomeOption(int value)
{
// validate parameter, store it etc.
// NO NEED TO CALL NOTIFY HERE - WILL BE HANDLED BY ANNOTATION
}
In JUnit for example, we have #Before or #After annotations, and I am wondering if JUnit has own annotations parser that handles method annotated this way, or this kind of behavior can be done simpler, since annotations can be #Retention(value=RUNTIME).
I know that in this example it might look over-complicated and calling notifyListeners() is much simper, but I wan't to know if annotation can be used the way I described, and if yes, can i get some tips? I don't expect ready solution, just a hint if this is possible and what should I take in consideration.
yes, you can do it but you have to use a framework or write one by yourself. you can use for example spring aspects and #After advice (or any other proxy mechanism). you can also use full aspectj for this. another option is to write it by yourself using reflection api. in last case you will need some kind of inversion of control - some mechanism that will launch your method and then the other method
In annotations you need a class that checks for it. they don't work on themselves.
The way systems check for them are with reflection.
Annotation<NotifyAnnotation> a = method.getAnnotation();
And explicitly call their methods
a.notifyListeners(a.evt);
I can't see any advantage with your case. but I see full of disadvantages. They should not be used in actual coding, just for test systems or similar scenarios, where an external system has control on your class.
It could be do that using bytecode manipulation (JAssist, Asm, Java Rocks ...). All the classes would be instantiated thru a Factory that would identify annotated methods and would inject in the first line of this method a call to the method specified in its annotation.