Migration: JUnit 3 to JUnit 4: TestSuite - regex

I was recently working with JUnit 3, but I decided to migrate to JUnit 4. Now Im facing the following problem:
I was using a TestSuite with JUnit 3, where I ran all java-Testclasses whose names matched a pattern like "*TestMe.java".
I've got a hundred tests which were named like this.
Now, with JUnit 4 I have to name them explicitly to call them in a TestSuite.
#RunWith(Suite.class)
#Suite.SuiteClasses(
{
FirstTestMe.class,
SecondTestMe.class,
ThirdTestMe.class,
})
public class TestMe
{
/**
* Constructor.
*/
private TestMe()
{
super();
}
}
This is really uncomfortable and I possibly might forget to list some tests. Also, when I create a new one, I must add it there.
Is there any solution how to call those Test-Classes with a Regex or something else?
Also, one additional question: each method which is not a test, but maybe used in a test-class must be annotated with #Ignore?
I run those test-classes without any error, so I guess it is not necessary?

You may want to have a look at the post migrate-tests-from-junit-3-to-junit-4 which discusses exactly what you want.
See if Dynamically create a Test Suite in JUnit 4 or Run all tests in Junit 4 helps.

Add the #Test annotation above your test method.
public class TestMe
{
#Before
public void setUp() {
}
#Test
public void myFirstTest() {
}
}

For your first question, if you want to use a Test Suite in JUnit 4, then there isn't any option but to list all of the classes explicitly. If, however, you want to run all classes in a package, or in a project, you can just right click on the package/project in Eclipse and select Run as JUnit test. If you're using ant or maven surefire, you can specify the tests to run with a *Test.java or similar.
You don't have to annotate those methods which are not test methods with #Ignore.
The (major) difference between JUnit 3 and JUnit 4 is the use of annotations. So it JUnit3, you extend TestCase and name all of your methods testXXX. In JUnit 4, you don't have to extend TestCase, but you do have to annotate all of your test methods with #Test. So therefore, any methods not marked with #Test don't get run as test. Of course, there are other annotations such as #Before and #After, which replace setUp() and tearDown().

There is an open source library ClasspathSuite. It allows you to use regular expressions to specify what class/package names should be or should not be included in your test suite.
Here's an example of use which includes everything in two packages but not in a third package. It also excludes another specific class.
#ClassnameFilters( { "com.javaranch.*test.*", "net.jforum.*test.*", "!com.javaranch.test.web.*", "!.*All_JForum_Functional_Tests" })

Related

Spock verify method call of newly created instance

I'm trying to verify some methods are called for a newly created instance.
I followed Spock guide of mock constructor but it says too few invocations.
Too few invocations for:
3 * mockStep.addTarget(_) (0 invocations)
Unmatched invocations (ordered by similarity):
None
Pasting my code here...
public class Workflow {
public void createStep() {
Step step = new Step();
step.addTarget("A");
step.addTarget("B");
step.addTarget("C");
}
}
class WorkflowTest extends Specification {
Workflow workflow
def setup() {
workflow = new Workflow()
}
def "each new step should have 3 targets" () {
given:
def mockStep = Mock(Step)
GroovySpy(Step, global: true)
new Step() >> mockStep
when:
workflow.createStep()
then:
3 * mockStep.addTarget(_)
}
}
In the above code I'm trying to let all new Step() returns the mocked Step and to verify the mockStep.addTarget() is called 3 times. When I ran in debug mode, it seems Step step = new Step(); still returns a new instance instead of the mocked Step.
Don't use dirty tricks like global Groovy mocks but refactor for decoupling, dependency injection and the resulting better testability instead. Please read the "general comments" and "some more remarks" sections of my answer here for a reason why you should refactor. I do not want to repeat everything here.
As for the technical reason why your global Groovy mock does not work from Java code, I am quoting the Spock manaual:
When should Groovy mocks be favored over regular mocks?
Groovy mocks should be used when the code under specification is
written in Groovy and some of the unique Groovy mock features are
needed. When called from Java code, Groovy mocks will behave like
regular mocks. Note that it isn’t necessary to use a Groovy mock
merely because the code under specification and/or mocked type is
written in Groovy. Unless you have a concrete reason to use a Groovy
mock, prefer a regular mock.
Update:
The quickest way to refactor is to separate creating the step from adding targets. Actually the name createStep implies the method does just that. But instead it also adds targets. Use two methods for that and a method doing the workflow. Then you can use a Spy for stubbing createStep (which returns the created Step instance) and then check interactions if you really think that should be tested at all. Checking internal interactions is often a code smell (over-specification).
Alternatively, add a factory class for steps and inject an instance into the workflow class. Then you can easily mock the factory class and make it return a mock step.
If you don't understand what I mean by the two alternatives, please let me know.
This is a beta feature and no grantee it will work as expected and it will be depending on the version you are using .
Please refer to official documentation

Using both Arquillian and PowerMock in the same JUnit test

I would like to use the features of both Arquillian and PowerMock in the same JUnit 4 test.
The problem is that both products are JUnit Runners which should be used with #RunWith, and this is not possible to use multiple #RunWith on the same test class, or to put multiple Runners class in the same #RunWith annotation.
Do you know any way to do that ?
You can use PowerMock without using the runner if you use the PowerMockRule (which is a TestRule). From the PowerMockRule:
Since version 1.4 it's possible to bootstrap PowerMock using a JUnit
Rule instead of using the PowerMockRunner and the RunWith annotation.
This allows you to use other JUnit runners while still benefiting from
PowerMock's functionality. You do this by specifying:
#RunWith(Arquillian.class);
public class MyTest {
#Rule
PowerMockRule rule = new PowerMockRule();
// Tests goes here
...
}
See also the answers to Junit Parameterized tests together with Powermock - how? and the following thread in the PowerMock google group: Using PowerMock without the RunWith?.
No, you either need to:
use one and create a test base class that does the things you wanted the other runner to do.
separate your test into multiple tests, each using different runners.
JUnit4 only supports one #RunWith annotation, and JUnit4's #RunWith annotation doesn’t accept multiple runners.
Reference: project13

TestNG #BeforeTest equivalent in JUnit

I found the comparison at http://www.mkyong.com/unittest/junit-4-vs-testng-comparison/. How to prepare something like #BeforeTest in JUnit?
As I understand it, BeforeTest specifies a method which is run before a set of tests is run, and defineable for that set of tests. There isn't an equivalent grouping in JUnit, except for normal Suites, so you have to define a suite and use #BeforeClass and #AfterClass in your suite as normal.
If you want more complex behaviour, see TestRule, in particular ExternalResource.
Not as familiar with TestNG, but from my understanding you can do something similar it with a combination of Categories, a Suite, and #BeforeClass/#AfterClass.
For example:
import org.junit.BeforeClass;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Categories.class)
#SuiteClasses(MyClassTest.class)
#IncludeCategory(IntegrationTest.class)
public class StaticTests {
#BeforeClass
public static void setUp() {
System.out.println("Hello, World!");
}
}
Then within your tests flag things as #Category(IntegrationTest.class) and you'll have a logical grouping of tests–from multiple different test classes–which you can run initialization around.
Categories let you flag specific tests for inclusion in the suite, though it is also possible (if you separate out by class in the first place) just to include the relevant ones in the suite or have them inherit from a base class that has that configuration in it. Which one is best depends on how you like to group your tests and your specific use cases.
As Matthew Farwell mentions, there's also TestRules which give you a little finer-grained control for setting up around a set of tests.

Correct way to metaprogram in grails so its available in unit tests

I can add a method to the java Integer type in Groovy with the lines:
ExpandoMetaClass.EnableGlobally()
Integer.metaClass.gimmeAP = {->return 'p'}
I don't know why I'd need that, but it gets the point across. Now I can make calls to Integers and get back a 'p'. Now lets say I want this in a grails app so I can make calls in the domain objects. The specific problem I'm having is that when I put those metaprogramming lines in the bootstrap all the metaprogramming isn't available in the unit tests, so my unit tests are failing with errors like "No method gimmeAP for java.lang.Integer" or something like that.
How do I either include the metaprogramming better, or execute that part of the bootstrap so I can use my tricked out syntax in unit tests?
I have seen this question: Grails - Making Methods Globally Available and Metaclass Programming and it seems my line ExpandoMetaClass.EnableGlobally() may fix his problem, but am I using it right?
Bootstrap isn't executed for unit tests. I would personally prefer to create a mockFoo method that does the above meta programming, and Then I will call the mockFoo from the test setup.
Also look at the GrailsUnitTestCase.registerMetaClass. Register metaclass before you add mock methods, so that they don't leak in other tests.
registerMetaClass(SecurityUtils)
SecurityUtils.metaClass.'static'.getSubject = { ->
return [logout: { return true } ] as Subject
}
I know you want to make your dynamic methods available to all unit tests, but there's nothing such as bootstrap for unit tests. So you have to do it in each test.
You can create a MockHelper with a static method, and call it from test setUp.

Does anyone know how to select parts of test methods in a test case run in a test suite?

For example, a test case named ExampleTest
ExampleTest {
testA{};
testB{};
testC();
}
I could run all this class with TestSuite.addTestSuite(ExampleTest.class);
but, how to select testA and testB run into TestSuite?
2 Ideas:
See if it makes sense to split ExampleTest into 2 test classes based on your partition
Otherwise use Categories to tag your tests and then run tests which belong to a specific category. Its simpler in NUnit, JUnit seems to require you to create an empty/ marker interface to get this done. A sample link with code.