TestNG #BeforeTest equivalent in JUnit - unit-testing

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.

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

Migration: JUnit 3 to JUnit 4: TestSuite

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" })

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.

Unit Tests for JPA/Persistence in General

How/would you test super-simple methods that are built on a persistence engine. I'm going to use JPA but any persistence mechanism I'm sure has its equivelents.
For example...
#Entity
public class Category {
#Id #GeneratedValue
private long id;
#NotNull #NotEmpty
private String name;
#NotNull
#ManyToOne
private User user;
//...Getters/Setters...
}
#Stateless
public void CategoryServiceImpl implements CategoryService {
#PersistenceContext EntityManager entityManager;
public void addCategory(Category input) {
entityManager.persist(input);
}
}
What kind of tests would be useful for addCategory. I can see the usefulness of TDD and unit testing but I'm just not sure what kinds of tests to do for simple methods like that. Not really looking for "how" to create the tests but "what" to test.
One philosophy is to be very hard-nosed about unit testing (before I explain what I mean, let me say that I rarely follow this philosophy myself). You are testing that this unit does what it is supposed to do, not that any depedent software (such the the persistence mechanism) works.
So this method of your receives a parameter "input" and passes it to entityManager.persist. That's it's job. So we use a mocking framework of some sort to get a mock entityManager, and we verify that indeed the parameter passed to the call of addCategory is received my the entityManager. That's it. We've tested all the responsibilities of the method.
In more complex scenarios this appraoch is pretty useful, you test all the conditionals in the method and pick up all sorts of "off-by-one" and misuse of null reference errors etc.
For something like this example I'm not convinced that we are going to find the interesting bugs.
So I'd be setting up little suites of tests using a real EntityManager, which push the boundaries of the data. And yes, this isn't truly "Unit" testing, but I don't care - I want to find defects!
For example:
Create a category object with an empty name
Call Add Category
What should happen? I assume that we intend that an exception be thrown? So we test that indeed that's what happens.
Some more tests:
Insert, then retrieve - verify all fields
Insert, then insert a duplicate, what error do we expect
and so on.
Instead of integration testing against an existing database you can perform decent unit tests by running your tests against an embedded in memory database like h2 which has been configured to create all its tables based on the annotations on connection. This works well for us for a database of about two hundred tables.