pvillega’s posterous

pvillega’s posterous

Pere Villega  //  Born in Barcelona, living in Dublin, and tagged as geek since youth. Developer in the path to becoming a software architect. I swear this is not a proper blog :)

Feb 16 / 7:26am

EasyMock

EasyMock provides Mock Objects for interfaces in JUnit tests by generating them on the fly using Java's proxy mechanism. A Mock Object is a test-oriented replacement for a collaborator. It is configured to simulate the object that it replaces in a simple way. In contrast to a stub, a Mock Object also verifies whether it is used as expected. EasyMock creates mock objects using the java.lang.refect.Proxy object. When a mock object is created, a proxy object takes the place of the real object. The proxy object gets its definition from the interface or class you pass when creating the mock. EasyMock has two sets of APIs. One is intended for creation and manipulation of mock objects that are based on interfaces, the other on classes (org.easymock.EasyMock and org.easymock.classextensions.EasyMock respectively). Both provide the same basic functionality; however classextensions does not have quite as extensive as an API as the regular EasyMock does.

Basics

Similar to JUnit a mock object in EasyMock has a life cycle of 4 steps: create, expect, replay and verify. These steps are used to record the expected behaviour of the object in the test and to validate the result. If the verify step fails the test will fail. Before creating an object with EasyMock you must know there are 3 types of objects defined:

  • Regular: A test fails if a method is called that is not expected or if a method that is expected is not called. Order of method calls does not matter.
  • Nice: A test fails if a method is expected but not called. Methods that are called but are not expected are returned with a type appropriate default value (0, null or false). Order of method calls does not matter.
  • Strict: A test fails if a method is called that is not expected or if a method that is expected is not called. Order of method calls does matter.

Creating mock objects

There are two main ways to create a mock object using EasyMock, directly and through a mock control. When created directly, mock objects have no relationship to each other and the validation of calls is independent. When created from a control, all of the mock objects are related to each other. Examples of these ways are:

Direct creation of mock objects

@Overridepublic

void setUp() {

UserDAO userDAO = EasyMock.createMock(UserDAO.class);

CustomerDAO customerDAO = EasyMock.createMock(CustomerDAO.class);

}

Creation of a mock object using a control

@Overridepublic

void setUp() {

IMocksControl mockCreator = EasyMock.createControl();

UserDAO userDAO = mockCreator.createMock(UserDAO.class);

CustomerDAO customerDAO = mockCreator.createMock(CustomerDAO.class);

}

The API to create mock objects consists on 3 versions of the method createMock, one for each type of object: createMock, createNiceMock and createStrictMock.

Recording Behaviour

Once we have created our mock objects we need to record its behaviour to be able to validate it later. There are three groups of scenarios that exist when recording behaviour: void methods, non void methods and methods that throw exceptions. Void methods are the easiest behaviour to record. Since they do not return anything, all that is required is to tell the mock object what method is going to be called and with what parameters. This is done by calling the method just as you normally would.

Code being tested

foo.bar();

String string = “Parameter 2”;

foo.barWithParameters(false, string);

Mocking the behavior

Foo fooMock = EasyMock.createMock(Foo.class);

fooMock.bar();

fooMock.barWithParameters(false, “Parameter 2”);

When methods return values a mock object needs to be told the method call and parameters passed as well as what to return. The method EasyMock.expect() is used to tell a mock object to expect a method call.

Code to be tested

String results = foo.bar();

String string = “Parameter 2”;

BarWithParametersResults bwpr = foo.barWithParameters(false, string);

Mocking the behaviour

Foo fooMock = EasyMock.createMock(Foo.class);

EasyMock.expect(foo.bar()).andReturn(“results”);

EasyMock.expect(foo.barWithParameters(false, “Parameter 2”)).andReturn(new BarWithParametersResults());

In order to be able to test that a method throws the appropriate exceptions when required, a mock object must be able to throw an exception when called.

Code to be tested

try {

String fleName = “C:\tmp\somefle.txt”;

foo.bar(fleName);

} catch (IOException ioe) {

foo.close();

}

Mocking the behaviour

Foo fooMock = EasyMock.createMock(Foo.class);

EasyMock.expect(fooMock.bar(“C:\tmp\somefle.txt”)) .andThrow(new IOException());

foo.close();

There are times where a method will be called multiple times or even an unknown number of times. EasyMock provides the ability to indicate those scenarios with the .times(), .atleastOnce() and .anyTimes() methods.

Replaying and validating

Once the behaviour of the mock objects has been recorded with expectations, the mock objects must be prepared to replay those expectations. Mock objects are prepared by calling the replay() method and passing it all of the mock objects to be replayed.

   Foo fooMock = EasyMock.createMock(Foo.class);

EasyMock.expect(fooMock.doSomething(parameter1, parameter2)).andReturn(new Object());

EasyMock.replay(fooMock);

The final step in the mock object life cycle is to validate that all expectations were met. That includes validating that all methods that were expected to be called were called and that any calls that were not expected are also noted. To do that, EasyMock.verify() is called after the code to be tested has been executed. The verify() method takes all of the mock objects that were created as parameters, similar to the replay

() method.

   Foo fooMock = EasyMock.createMock(Foo.class);

EasyMock.expect(fooMock.doSomething(parameter1,Parameter2)).andReturn(new Object());

EasyMock.replay(fooMock);

Bar bar = new Bar();

bar.setFoo(fooMock);

EasyMock.replay(fooMock);

bar.runFoo();

EasyMock.verify(fooMock);

Real example

EasyMock can be quite confusing so I add an example of a "real case" scenario on how it would be used to mock an object in a certain unit test:

     private LoginServiceImpl service;

private UserDAO mockDao;

@Before

public void setUp() {

service = new LoginServiceImpl();

mockDao = createStrictMock(UserDAO.class);

service.setUserDAO(mockDao);

}

public void testRosyScenario() {

User results = new User();

String userName = "testUserName";

String password = "testPassword";

String passwordHash = "534h345kfswd3453"; //this should be a hash of the password

expect(mockDao.loadByUsernameAndPassword(eq(userName), eq(passwordHash)))

.andReturn(results);

replay(mockDao);

assertTrue(service.login(userName, password));

verify(mockDao);

}

Credit of this text to the amazing refcard of Dzone: http://refcardz.dzone.com/refcardz/junit-and-easymock

Loading mentions Retweet

Comments (0)

Feb 16 / 7:16am

JUnit

JUnit is a testing framework for Java applications. It was one of the first testing frameworks for Java and it's a widespread use in the community. The framework simplifies the development of unit tests and the current IDE's make even easier building those tests from existing classes and running them. The latest version available in the official website is JUnit 4.5. In this post I won't enter the discussion about TDD or how to build a useful test, I will just show the basics to use JUnit for this purpose. A test case is the basic unit of testing in JUnit and is defined by a class extending junit.framework.TestCase. The TestCase class provides a series of methods that are used over the life cycle of a test. This life cycle consist on 3 steps (setup, test method, tear down) run in sequence for each test method. A test method is defined by any method that fits the following criteria:

  • It must be public.
  • It must return void.
  • The name must begin with “test”.

The test case can have some optional life cycle methods:

  • public void setUp(): executed before each test method
  • public void tearDown(): executed after each test method
  • public void setUpClass(): executed before starting the test case
  • public void tearDownClass(): executed after finishing the test case

These methods can be used to load resources needed for the test, like database connections. Inside each test method we have some assertions that tell us if the test was successful or not. If a method finishes with all the assertions succeeding the test method is a success, if one of them fails the test method fails. The list of assertions we can use is:

  • assertNull(Object x): Validates that the parameter is null
  • assertNotNull(Object x): Validates that the parameter is not null
  • assertTrue(boolean x): Validates that the parameter is true
  • assertFalse(boolean x): Validates that the parameter is false
  • assertEquals(Object x, Object y): Validates that the two objects passed are equal based on the equals(Object obj1, Object obj2) method
  • assertSame(Object x, Object y): Validates that the two objects passed are equal based on the == operator
  • assertNotSame(Object x, Object y): Validates that the two objects passed are not equal based on the ==  operator
  • fail(): Fail the test.

Following the rules above we can create tests for both JUnit 3 and JUnit 4.5. JUnit 4.5 adds to the mix some annotations that allows us to mark the methods to use in the tests. These annotations are:

  • @After: Method will be executed after each test method (similar to the tearDown() method in JUnit 3.x). Multiple methods may be tagged with the @After annotation, however no order is guaranteed.
  • @AfterClass: Method will be executed after all of the test methods and tear down methods have been executed within the class. Multiple methods may be tagged with the @AfterClass annotation, however no order is guaranteed.
  • @Before: Method will be executed before each test method (similar to the setUp() method in JUnit 3.x). Multiple methods may be tagged with the @Before annotation, however no order is guaranteed.
  • @BeforeClass: Executed before any other methods are executed within the class. Multiple methods may be tagged with the @BeforeClass annotation, however no order is guaranteed.
  • @Ignore(String): Used to temporarily exclude a test method from test execution. Accepts an optional String reason parameter.
  • @Parameters: Indicates a method that will return a Collection of objects that match the parameters for an available constructor in your test. This is used for parameter driven tests.
  • @RunWith(Class): Used to tell JUnit the class to use as the test runner. The parameter must implement the interface junit.runner.Runner.
  • @SuiteClasses(Class []): Tells JUnit a collection of classes to run.  Used with the @RunWith(Suite.class) annotation is used.
  • @Test(Class, Timeout): Used to indicate a test method. Same functionality as naming a method public void testXYZ() in JUnit 3.x. The class parameter is used to indicate an exception is expected to be thrown and what the exception is. The timeout parameter specifies in milliseconds how long to allow a single test to run. If the test takes longer than the timeout, it will be considered a failure.

Another benefit of using JUnit 4.5 is that you don't need to extend any class, that way any POJO with the proper annotations can be used as a test unit. One example of a JUnit 4.5 test class using the annotations:

public class FooTestCase {

private Foo foo;

@Before

public void buildFoo() {

foo = new Foo();

}

@Test

public void testGoodResultsBar() {

String param1 = "parameter1";

Stringresults = foo.bar(param1);

assertNotNull("results was null", results);

assertEquals("results was not 'good'", "good", results);

}

@Test

public void testBadResultsBar() {

try {

String results = foo.bar(null);

} catch (NullPointerException npe) {

return;

}

fail();

}

@After

public void closeFoo() {

foo.close();

}

}

You can create a Suite to run several tests at once. This is not really necessary with the current IDE plugins, but if you are interested this example code:

@RunWith(Suite.class)

@SuiteClasses({FooTest.class, BarTest.class})

public class AllTests {

public static Test suite() {

return new JUnit4TestAdapter(AllTests.class);

}

}

will run the tests from classes FooTest and BarTest together. Credit of this text to the amazing refcard of Dzone: http://refcardz.dzone.com/refcardz/junit-and-easymock

Extensions

JUnit has a rich ecosystem of extensions to enhance its capabilities. In this section I will mention some of the most interesting ones.

DBUnit

DBUnit is a JUnit extension (also usable with Ant) targeted for database-driven projects that, among other things, puts your database into a known state between test runs. You can find more information in its wiki page and a guide on how to start here.

DOF

The Dependent Object Framework (DOF) enables efficient JUnit testing and Test Driven Development against code that depends on objects that are persisted (e.g., database). You can read an introduction to the framework at the JUnit site.

EJB3Unit

EJB3Unit is a JUnit extension and can execute automated standalone JUnit tests for all EJB 3.0 conform JEE projects. The out of container test approach leads to short build-test-cycles, because no container deployment is necessary anymore. EJb3Unit uses an internal in memory database by default. Alternatively a user defined database can be specified. You can follow these steps to download a sample project on how to use EJB3Unit.

T2 Framework

T2 is a fully automatic, trace-based random testing tool, featuring in-code specifications and reflexive testing. It is also almost interactive; depending on the complexity of your class it can respond in less than a second. T2 checks for internal errors, run time exceptions, method specifications, and class invariant. Unlike other testing tools, they are placed in the class we want to specify. What makes this tool useful is that randomness in testing that helps to detect unexpected errors.

Loading mentions Retweet

Filed under // java junit unit testing

Comments (0)

Feb 16 / 6:50am

Testability Explorer

Testability Explorer is a Java-based library to validate how testable is your application. It analyses Java bytecode and computes how difficult it will be to write unit tests for the code. It attempts to help you quantitatively determine how hard your code is to test, and where to focus to make it more testable. Although it may not seem so useful at first, it's a handy tool for several reasons:

  • Testable code is usually well designed code
  • Helps to guide you when refactoring your application
  • It integrates with Maven and Ant, running automatically (no need to remember to run it)
  • Enforcing testable code helps your continuous integration process

Running the application

Download the zip package with the shell script in it, uncompress it an run it with:

$ testability.sh [classes_and_packages] [-cp classpath] [options]

At least one of classes_and_packages or -cp is required.

An alternative is to download the jar and launch it using java -jar, as in fact the shell script just does that. Know that the application tests only jars or class files, not java files. It runs over your already compiled (bytecode) classes.

Running with Maven

The Maven plugin is not yet released to the Maven central repository. To use it, you'll need to build it from source:

$ svn checkout http://testability-explorer.googlecode.com/svn/trunk/ testability-explorer

$ cd testability-explorer

$ mvn install

Now you can add it to your Maven pom.xml:

group id:       com.google.testability-explorer
artifact id: maven2-testability-plugin
version: 1.3.1-SNAPSHOT

and when you run mvn site, you should have a testability.html file under target/site/. See the available options by running:

mvn help:describe -Dplugin=com.google.testability-explorer:maven2-testability-plugin -Ddetail

Running with Ant

There's an explanation of the Ant task here. The most common usage is including the task into Ant and call it using: If you have doubts check the Readme file in the wiki of the project

What is it testing?

Before knowing if Testability Explorer is a good or bad idea, you must know what it test. The application mainly checks for Injectability of classes and the absence of Global State, two things that facilitate unit testing. High injectability is good because it gives the test plenty of choices where to intercept the code under tests and make the test as small as possible. Similarly low global state will aid in isolating the tests from each other. Besides that, other parameters are analysed to determine how testable a class is. One of the things the application checks is the "Law of Demeter", which says that your code should only talk to its immediate collaborators. The most common pattern that violates the Law of Demeter is this:

interface Foo {

  public ComplexObject getTheObject();

}

class MyClass {

  private Foo myDependency;

  public void method() {

    myDependency.getTheObject().doThingWithIt();

  }

}

This is a bad thing to do, because it makes testing MyClass harder. If we want to set a Mock, Stub, or Fake object into myDependency, we will be forced to implement doThingWithIt() on that object, in a way that keeps MyClass happy. That without considering how hard it may be to track a NPE in that point. As you can see, the application does an intensive check on possible pitfalls of testability. You can find more detail in these links:

Loading mentions Retweet

Comments (0)

Feb 16 / 6:22am

TestNG

TestNG is a testing framework for the Java programming language inspired by JUnit and NUnit but introducing some new functionalities that purport to make it more powerful and easier to use. TestNG is designed to cover all categories of tests, including unit, functional, and integration tests. You may be thinking that we already have JUnit, which evolved a lot on versions 4.0 and 4.5 and it's being used in lots of project, so why do we need TestNG? Well, after checking the net for an answer to this I read that JUnit has always been a unit-testing framework, meaning that it was built to facilitate testing single objects, and it does so quite effectively. TestNG, on the other hand, was built to address testing at higher levels, and consequently, has some features not available in JUnit. One of these features is the flexibility of TestNG. While the code looks quite similar while comparing a JUnit tests and a TestNG one, TestNG doesn't require you to have public or static methods for certain steps of the lifecycle, while JUnit does. This gives the TestNG users more flexibility when developing tests based in POJOs. Another important difference is the existence of dependencies. With JUnit you can't mark a test as depending in another, thus makiung impossible to specify a test order unless you use some tricks like namig of tests. With TestNG you can declare dependencies, so one test won't run until the dependency has been tested and succeeded. TestNG also generates an XML file with a list of failed tests, so you can run only these tests once you fix the errors, something quite handy when you application has some thousands of test units and that JUnit doesn't provide (although IDE's plugins remove this difference). And last but not least TestNG offers parametric testing. This means you can define groups of parameters for a test in an xml file and use it for the test, allowing you to test the result with different values without having to write several test cases. There are some other minor differences but as you can see TestNG is an extension of the capabilities of JUnit. It's true you can do the same (or something quite similar) with JUnit and some plugins, but TestNG provides these features by default. TestNG is integrated with Maven by default and can be called as an Ant task. It has pluguins for all the popular IDE (Eclipse, Netbeans, IDEA).

TestNG

You can find the documentation of TestNG in the official page, and a book is available that describes the framework in more detail. Before starting, if you have any existing JUnit test you can run JUnitConverter to migrate them automatically to TestNG, so you can see the differences. Writing a test with TestNG is typically a three-step process:

  • Write the business logic of your test and insert TestNG annotations in your code.
  • Add the information about your test (e.g. the class name, the groups you wish to run, etc...) in a testng.xml file or in build.xml.
  • Run TestNG.

In TestNG a suite is represented by one XML file. It can contain one or more tests and is defined by the <suite> tag. A test is represented by <test> and can contain one or more TestNG classes. A TestNG class is a Java class that contains at least one TestNG annotation. It is represented by the <class> tag and can contain one or more test methods. A test method is a Java method annotated by @Test in your source. A TestNG test can be configured by @BeforeXXX and @AfterXXX annotations which allows to perform some Java logic before and after a certain point. The list of valid annotations is:

  • @BeforeSuite: The annotated method will be run before all tests in this suite have run.
  • @AfterSuite: The annotated method will be run after all tests in this suite have run.
  • @BeforeTest: The annotated method will be run before the test.
  • @AfterTest: The annotated method will be run after the test.
  • @BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
  • @AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
  • @BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
  • @AfterClass: The annotated method will be run after all the test methods in the current class have been run.
  • @BeforeMethod: The annotated method will be run before each test method.
  • @AfterMethod: The annotated method will be run after each test method.
  • Parameters of these annotations:
    • alwaysRun: For before methods (beforeSuite, beforeTest, beforeTestClass and beforeTestMethod, but not beforeGroups): If set to true, this configuration method will be run regardless of what groups it belongs to. For after methods (afterSuite, afterClass, ...): If set to true, this configuration method will be run even if one or more methods invoked previously failed or was skipped.
    • dependsOnGroups: The list of groups this method depends on.
    • dependsOnMethods: The list of methods this method depends on.
    • enabled: Whether methods on this class/method are enabled.
    • groups: The list of groups this class/method belongs to.
    • inheritGroups: If true, this method will belong to groups specified in the @Test annotation at the class level.
  • @DataProvider: Marks a method as supplying data for a test method. The annotated method must return an Object[][] where each Object[] can be assigned the parameter list of the test method. The @Test method that wants to receive data from this DataProvider needs to use a dataProvider name equals to the name of this annotation.
    • name: The name of this DataProvider.
  • @Factory: Marks a method as a factory that returns objects that will be used by TestNG as Test classes. The method must return Object[].
  • @Parameters: Describes how to pass parameters to a @Test method.
    • value: The list of variables used to fill the parameters of this method.
  • @Test: Marks a class or a method as part of the test.
    • alwaysRun: If set to true, this test method will always be run even if it depends on a method that failed.
    • dataProvider: The name of the data provider for this test method.
    • dataProviderClass: The class where to look for the data provider. If not specified, the data provider will be looked on the class of the current test method or one of its base classes. If this attribute is specified, the data provider method needs to be static on the specified class.
    • dependsOnGroups: The list of groups this method depends on.
    • dependsOnMethods: The list of methods this method depends on.
    • description: The description for this method.
    • enabled: Whether methods on this class/method are enabled.
    • expectedExceptions: The list of exceptions that a test method is expected to throw. If no exception or a different than one on this list is thrown, this test will be marked a failure.
    • groups: The list of groups this class/method belongs to.
    • invocationCount: The number of times this method should be invoked.
    • invocationTimeOut: The maximum number of milliseconds this test should take for the cumulated time of all the invocationcounts. This attribute will be ignored if invocationCount is not specified.
    • successPercentage: The percentage of success expected from this method
    • sequential: If set to true, all the methods on this test class are guaranteed to run sequentially, even if the tests are currently being run with parallel="true". This attribute can only be used at the class level and it will be ignored if used at the method level.
    • timeOut: The maximum number of milliseconds this test should take.
    • threadPoolSize: The size of the thread pool for this method. The method will be invoked from multiple threads as specified by invocationCount. Note: this attribute is ignored if invocationCount is not specified

A test is considered successful if it completed without throwing any exception or if  it threw an exception that was expected (see the documentation for the expectedExceptions attribute found on the @Test annotation). Your test methods will typically be made of calls that can throw an exception, or of various assertions (using the Java "assert" keyword).  An "assert" failing will trigger an AssertionErrorException, which in turn will mark the method as failed (remember to use -ea on the JVM if you are not seeing the assertion errors). TestNG also include JUnit's Assert class, which lets you perform assertions on complex objects (check JUnit page).

Examples

Next some examples of TestNG in use. First a piece of code that shows how to declare some groups for our Tests, so we run one group or another depending on our needs:

public class Test1 {

@Test(groups = { "functest", "checkintest" })

public void testMethod1() {

}

@Test(groups = {"functest", "checkintest"} )

public void testMethod2() {

}

@Test(groups = { "functest" })

public void testMethod3() {

}

}

You can define the groups at class level adding any method-specific group if needed:

@Test(groups = { "checkin-test" })

public class All {

@Test(groups = { "func-test" )

public void method1() { ... }

public void method2() { ... }

}

Parameters can be defined in the TestNG XML file, and be called like:

@Parameters({ "first-name" })

@Test

public void testSingleString(String firstName) {

System.out.println("Invoked testString " + firstName);

assert "Cedric".equals(firstName);

}

@Parameters({ "datasource", "jdbcDriver" })

@BeforeMethod

public void beforeTest(String ds, String driver) {

m_dataSource = ...; // look up the value of datasource

m_jdbcDriver = driver;

}

You can even define default values in case the parameter is not defined in the XML file:

@Parameters("db")

@Test

public void testNonExistentParameter(@Optional("mysql") String db) {

//code

}

Data Providers can be used instead of parameters to run the test using a set of values:

//This method will provide data to any test method that declares that its Data Provider

//is named "test1"

@DataProvider(name = "test1")

public Object[][] createData1() {

return new Object[][] {

{ "Cedric", new Integer(36) },

{ "Anne", new Integer(37)},

};

}

//This test method declares that its data should be supplied by the Data Provider

//named "test1"

@Test(dataProvider = "test1")

public void verifyData1(String n1, Integer n2) {

System.out.println(n1 + " " + n2);

}

Or use some class as provider if it can be used for several test classes:

public static class StaticProvider {

@DataProvider(name = "create")

public static Object[][] createData() {

return new Object[][] {

new Object[] { new Integer(42) }

}

}

}

public class MyTest {

@Test(dataProvider = "create", dataProviderClass = StaticProvider.class)

public void test(Integer n) {

// ...

}

}

If you declare your @DataProvider as taking a java.lang.reflect.Method as first parameter, TestNG will pass the current test method for this first parameter. This is particularly useful when several test methods use the same @DataProvider and you want it to return different values depending on which test method it is supplying data for:

@DataProvider(name = "dp")

public Object[][] createData(Method m) {

System.out.println(m.getName()); // print test method name

return new Object[][] { new Object[] { "Cedric" }};

}

@Test(dataProvider = "dp")

public void test1(String s) {

}

@Test(dataProvider = "dp")

public void test2(String s) {

}

You can specify dependencies for your test, both on methods:

@Test

public void serverStartedOk() {}

@Test(dependsOnMethods = { "serverStartedOk" })

public void method1() {}

or on groups:

@Test(groups = { "init" })

public void serverStartedOk() {}

@Test(groups = { "init" })

public void initEnvironment() {}

//dependency on any group that starts with "init."

@Test(dependsOnGroups = { "init.* })

public void method1() {}

You can use Factories to create test objects dynamically:

public class WebTestFactory {

@Factory

public Object[] createInstances() {

Object[] result = new Object[10];

for (int i = 0; i < 10; i++) {

result[i] = new WebTest(i * 10);

return result;

}

}

public class WebTest {

private int m_numberOfTimes;

public WebTest(int numberOfTimes) {

m_numberOfTimes = numberOfTimes;

}

@Test

public void testServer() {

for (int i = 0; i < m_numberOfTimes; i++) {

// access the web page

}

}

}

There are other advanced functionalities like Dependency Injection or reporting available, but they are out of scope here. As you can see TestNG is, by default, much more versatile (and powerful) than JUnit.

TestNG and EJB3

With JUnit we have an extension available to test EJB 3.0. TestNG can make use of its capabilities ot test EJB without needing any external library. There's an example on how to use JBoss for this, and in the end of the post the author also mentions an structure used to test JSF + EJB. The key is to build a class that will setup the environment for you and use it in your test. Thanks to annotations we can tell TestNG how to manage that helper class, making our life easier and giuving us absolute control on what can it do.

Using JUnit extensions in TestNG

That's probably the killer functionality of TestNG. Thanks to its versability it allows you to use JUnit extensions, although with some restrictions (so you can't use 100% of them).

TestNG and JMockit

Any test framework needs a proper mock objects' framework to be able to test the application properly. JUnit has the well known EasyMock, but this framework is quite coupled with JUnit so it doesn't work for us. For TestNG the recommended framework is JMockit. You can check the official tutorial and this two parts tutorials for information on the framework.

Loading mentions Retweet

Filed under // java testng unit testing

Comments (0)

Jan 24 / 2:31pm

Testing WebServices

Hi there, long time no see ;) In my recent projects I've had some issues with web services and needed to debug the SOAP calls as the stack trace was not helping. Searching on a solution I found Axis has a nice proxy for web services, that lets you intercept the SOAP calls and see the output. You'll need the following jars:
  • axis-1.4.jar
  • axis-wsdl4j-1.5.1.jar
  • commons-loggin-1.1.1.jar
  • commons-discovery-20040218.194635.jar
and the code below:
 System.getProperties().setProperty("http.proxySet", "true");
 System.getProperties().setProperty("http.proxyHost", "127.0.0.1");
 System.getProperties().setProperty("http.proxyPort", "8080");

 /*specify wsdl*/
 String wsdlURL = "http://localhost/mantis/api/soap/mantisconnect.php?wsdl";
 /*specify name space*/
 String nmspace = "http://futureware.biz/mantisconnect";
 /*specify target service*/
 String srvname = "MantisConnect";
 /*specify target method*/
 String fncname = "mc_version";
 /*specify your query*/
 String query = "";

 /*defin serviceQN,portQN*/
 QName serviceQN = new QName(nmspace, srvname);
 QName portQN = new QName(nmspace, "MantisConnectPort");
 /*define service*/
 Service service = new Service(new URL(wsdlURL), serviceQN);
 /*execute soap*/
 Call call = (Call) service.createCall(portQN, fncname);
 //Pass params!
 //String result = (String)call.invoke(new Object[]{query});
 String result = (String) call.invoke(new Object[]{});
 System.out.println(result);

Then run the proxy program:
java -cp axis-1.4.jar org.apache.axis.utils.tcpmon
and set up a proxy on port 8080 to intercept calls. Customise the code (wsdl, namespace, etc), and run it. You'll see the input/output in your proxy.
Loading mentions Retweet

Filed under // java unit testing web service

Comments (0)

Aug 27 / 4:17am

Canoo WebTest

Canoo WebTest is a free Open Source tool for automated testing of web applications. Its power resides in how easily can you set up a functional test, using XML or Groovy, which allows you to add a new layer of validation to your web application. Canoo has a good integration with Groovy and Grails, but it can be used for applications built on any language, from Java to .Net, including scripting languages like Ruby on Rails, and it has a really good integration with Hudson which makes running the tests even easier. All in all, if your framework of choice doesn't have a similar tool (or the one it provides is lacking) you should check Canoo. It will improve both your development process and your application.
Loading mentions Retweet

Comments (0)