@RunWith(Parameterized.class)
@PrepareForTest(Helper.class)
public class ParameterizedPowerMock {
/**
* @RunWith(PowerMockRunner.class)
*
* The Main thing to look out for Here is the
* Parameterized Version of Powermock & @Rule
* i.e. PowerMockRule.
*
* For JUnit Parameterized Test cases the class
* needs to be annotated with @RunWith(Parameterized.class)
* and for Powermock the class needs to be annotated with
* @RunWith(PowerMockRunner.class), so a Test class at the same
* Time cannot be annotated with both @Runwith classes,
* So we are using here @Rule
*
* Two important points to be kept in mind for JUnit 4 Parameterized
* Test cases with PoweMock is that, and Rule and Test Class Constructor
* should be public
*
*/
//@Rule should be declared Public
public @Rule PowerMockRule rule = new PowerMockRule();
String param;
String expectedResult;
//The constructor should be declared Public
public ParameterizedPowerMock(String param, String expectedResult)
{
this.param = param;
this.expectedResult = expectedResult;
}
@Parameterized.Parameters
public static Iterable
Sunday, 22 March 2015
Parameterized Mocking with Powermock
Mocking Non Void Public Method
@Test
public void testnonVoidPublicMethod() throws Exception
{
Helper helper = PowerMockito.mock(Helper.class);
//PowerMockito.mockStatic(Helper.class);
//ArgumentCaptor captor = ArgumentCaptor.forClass(StringBuilder.class);
/**
* Mocking the result of Public Non Void Instance method
* Returning Result as an Answer implementation
*
*/
//PowerMockito.doAnswer(answerIsArgumentString()).when(helper,"nonVoidPublicMethod",
entity,stringBuilder);
/**
* Making the mocked behaviour of the method to throw an Exception
*
*/
PowerMockito.doThrow(new RuntimeException(" Mocked Exception ")).when(helper
,"nonVoidPublicMethod",entity,stringBuilder);
String ok= helper.nonVoidPublicMethod(entity,stringBuilder.append("ok Subhankar"));
/**
* We can keep Assert statements Here
*
*/
/**
* End of Assert Statements
*/
}
//This method returns the toString() version of the second argument of the method invoked
private static Answer answerIsArgumentString() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[1].toString());
return str;
}
};
}
//This method returns the toString() version of the first argument of the method invoked
private static Answer answerIsArgumentDate() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[0]).toString();
return str;
}
};
}
NEXT
Mocking Non Void private Method
@Test
public void testnonVoidPrivateMethod() throws Exception
{
Helper helper = PowerMockito.spy(new Helper());
/**
* Please Note that the PowerMockito.spy also takes the class type as
* an Instance and then its return type is void i.e. in this case no
* Mocked instance is available.
*/
/**
* Both the behaviours defined below are same,
* only one returns Answer implementation and other
* returns Normal Object
*
*/
//doAnswer(answerIsArgumentString()).when(helper,method
(Helper.class,"nonVoidPrivateMethod",entity.class,StringBuilder.class))
.withArguments(entity, stringBuilder);
doReturn("OKuuui").when(helper,method(Helper.class,"nonVoidPrivateMethod",Entity.class,
StringBuilder.class)).withArguments(anyObject(), anyObject());
/**
* This call will make the original method call Since, we are not
* calling with the mocked instance
*/
//String ok = new Helper().callNonVoidPrivateMethod(entity,stringBuilder.append("ok Subhankar"));
/*
* Now if we do invoke with the mocked instance create above we would get mocked behaviour
*
*/
String ok = helper.callNonVoidPrivateMethod(entity,stringBuilder.append("ok Subhankar"));
System.out.println("The nonVoidPrivateMethod Result is:" +ok);
}
//This method returns the toString() version of the second argument of the method invoked
private static Answer answerIsArgumentString() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[1].toString());
return str;
}
};
}
//This method returns the toString() version of the first argument of the method invoked
private static Answer answerIsArgumentDate() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[0]).toString();
return str;
}
};
}
NEXT
Mocking Non Void Private Static Method
@Test
public void testnonVoidPrivateStaticMethod() throws Exception
{
//It Mocks the static methods of the final class Helper
PowerMockito.mockStatic(Helper.class);
/**
* The Behaviour defining section
*/
/**
* Type 1
*
* In this version the parameters could be defined with Mockito Matchers
* Like anyObject(),anyInt() etc...
*
* The return value can also be specified as an Answer implementation
* with the help of API's like PowerMockito.doAnswer
* (<< An answer implementation >>) like answerIsArgumentString() as provided below.
*
*/
//PowerMockito.doReturn("ok").when(Helper.class, "nonVoidPrivateStaticMethod",
anyObject(),anyObject());
//PowerMockito.doCallRealMethod().when(Helper.class, "nonVoidPrivateStaticMethod",
anyObject(),anyObject());
/**
* any() is shorter alias of Matchers.anyObject()
*/
PowerMockito.doAnswer(answerIsArgumentDate()).when(Helper.class, "nonVoidPrivateStaticMethod",
any(),any());
//Here calling the mocked method with a Public Instance Method
//String ok = new Helper().callNonVoidPrivateStaticMethod(entity,stringBuilder.append("ok Subhankar"));
/**
* Now here we are calling the private static method, with a public static method and
* & since PowerMockito's mockStatic mocks all the static methods of the class
* so, if we do not mock the caller static method we wont get the desired result.
*
*/
PowerMockito.doCallRealMethod().when(Helper.class, "callNonVoidPrivateStaticMethodWithStatic",
anyObject(),anyObject());
/**
* End of Behaviour defined section
*
*/
//Now calling the mocked method with a Public Static Method
String ok = Helper.callNonVoidPrivateStaticMethodWithStatic(entity,stringBuilder.append("ok Subhankar"));
//System.out.println("The nonVoidPrivateStaticMethod Result is:" +ok);
}
//This method returns the toString() version of the second argument of the method invoked
private static Answer answerIsArgumentString() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[1].toString());
return str;
}
};
}
//This method returns the toString() version of the first argument of the method invoked
private static Answer answerIsArgumentDate() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[0]).toString();
return str;
}
};
}
NEXT
Mocking Non Void Public Static Method
@Test
public void testnonVoidPublicStaticMethod() throws Exception
{
//It Mocks the static methods of the final class Helper
PowerMockito.mockStatic(Helper.class);
/**
* The Behaviour defining section
*/
/**
* Type 1
*
* In this version the parameters could be defined with Mockito
* Matchers Like anyObject(), anyInt() etc...
*
* The return value can also be specified as an Answer implementation
* with the help of API's like PowerMockito.doAnswer
* (<< An answer implementation >>) like answerIsArgumentString() as provided below.
*
* the doCallRealMethod() returns the real Method implementation
*
*/
//PowerMockito.doReturn("ok").when(Helper.class, "nonVoidPublicStaticMethod",
anyObject(),anyObject());
//PowerMockito.doCallRealMethod().when(Helper.class, "nonVoidPublicStaticMethod",
anyObject(),anyObject());
//PowerMockito.doAnswer(answerIsArgumentDate()).when(Helper.class, "nonVoidPublicStaticMethod",
any(),any());
/**
* Type 2
*
* In this version the parameters to be defined as original objects to be matched instead of Matchers..
*
* The return value can also be specified as an Answer implementation with the help of
* API's like thenAnswer(<< An answer implementation >>) like answerIsArgumentDate()
* as provided below.
*
* the thenCallRealMethod() returns the real Method implementation
*
*/
/*when(Helper.nonVoidPublicStaticMethod(entity,stringBuilder)).thenCallRealMethod();
when(Helper.nonVoidPublicStaticMethod(entity,stringBuilder)).thenReturn("ok");
*/
when(Helper.nonVoidPublicStaticMethod(entity,stringBuilder)).thenAnswer(answerIsArgumentString());
/**
* End of Behaviour defined section
*
*/
String ok = Helper.nonVoidPublicStaticMethod(entity,stringBuilder.append("ok Subhankar"));
//System.out.println("The nonVoidPublicStaticMethod Result is:" +ok);
}
//This method returns the toString() version of the second argument of the method invoked
private static Answer answerIsArgumentString() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[1].toString());
return str;
}
};
}
//This method returns the toString() version of the first argument of the method invoked
private static Answer answerIsArgumentDate() {
return new Answer() {
public String answer(InvocationOnMock invocation) {
String str = (invocation.getArguments()[0]).toString();
return str;
}
};
}
NEXT
Wednesday, 18 March 2015
Mocking with Powermock
While I was discovering various features of Mocking, I came across two terms Mocks & Stubs, literal meaning of both these terms may seems synonumoys, but there is a fine line that separates them,
Here is the difference
All the scenarios are described in the code itself with comments, so it becomes easy for us to co-relate.
Mocks Vs Stubs:
I believe the biggest distinction is that a stub is already written with predetermined behavior. So we would have a class that implements the dependency (abstract class or interface most likely) we are faking for testing purposes and the methods would just be stubbed out with set responses. They wouldn't do anything fancy and we would have already written the stubbed code for it outside of your test. A mock is something that as part of our test we have to setup with your expectations. A mock is not setup in a predetermined way so you have code that does it in your test. Mocks in a way are determined at runtime since the code that sets the expectations has to run before they do anything. Tests written with mocks usually follow an initialize -> set expectations -> exercise -> verify pattern to testing. While the pre-written stub would follow an initialize -> exercise -> verify . The purpose of both is to eliminate testing all the dependencies of a class or function so our tests are more focused and simpler in what they are trying to prove. In order to mock behaviour, there are a number of tools available, they are Mockito, EasyMock, PowerMock etc. & there exists a fair and lot of resources on the cloud for each of them to learn about, but the thing that separates PowerMock from other is its ability to mock final classes. Here I am going to share a few scenarious of Mocking with PowerMock.All the scenarios are described in the code itself with comments, so it becomes easy for us to co-relate.
-
Mocking Non Void Public Static Method
Mocking Non Void Private Static Method
Mocking Non Void private Method
Mocking Non Void Public Method
Parameterized Mocking with Powermock
Mocking with Annotations
-
1) Helper.java
2) Entity.java
import java.sql.Date;
public class Entity {
Date benefitDate;
public Date getBenefitDate() {
return benefitDate;
}
public void setBenefitDate(Date benefitDate) {
this.benefitDate = benefitDate;
}
@Override
public String toString() {
return "Entity [benefitDate=" + benefitDate + "]";
}
}
&
public final class Helper {
private String formatDateTest(String str)
{
return new SimpleDateFormat("yyyy-MM-dd").format(new Date() );
}
/*public static String dataMethod() throws ParseException
{
return formatDate(null);
}*/
public String invokePrivate(String data)
{
return this.formatDateTest(data);
}
private static String formatDate(java.util.Date d) throws ParseException
{
System.out.println(" The date in formatDate is:"+d.toString());
SimpleDateFormat fromFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat toFormat = new SimpleDateFormat("MM/dd/yyyy");
String d1 = toFormat.format(fromFormat.parse(d.toString()));
return d1;
}
public static String writeEntityRecord(Entity entity) throws ParseException
{
String str = formatDate(entity.getBenefitDate());
return str;
}
private static String formatDateTestStatic(String str)
{
return new SimpleDateFormat("yyyy-MM-dd").format(new Date() );
}
public static String invokePrivateStatic(String data)
{
return formatDateTestStatic(data);
}
//Tested
public static String nonVoidPublicStaticMethod(Entity entity,StringBuilder stringBuilder)
{
return entity.toString()+stringBuilder.toString();
}
//Tested
private static String nonVoidPrivateStaticMethod(Entity entity,StringBuilder stringBuilder)
{
return entity.toString()+stringBuilder.toString();
}
public String nonVoidPublicMethod(Entity entity,StringBuilder stringBuilder)
{
return entity.toString()+stringBuilder.toString();
}
//Tested
private String nonVoidPrivateMethod(Entity entity,StringBuilder stringBuilder)
{
return entity.toString()+stringBuilder.toString();
}
public String callNonVoidPrivateStaticMethod(Entity entity,StringBuilder stringBuilder)
{
return nonVoidPrivateStaticMethod( entity, stringBuilder);
}
public static String callNonVoidPrivateStaticMethodWithStatic(Entity entity,StringBuilder stringBuilder)
{
return nonVoidPrivateStaticMethod( entity, stringBuilder);
}
public String callNonVoidPrivateMethod(Entity entity,StringBuilder stringBuilder)
{
return nonVoidPrivateMethod( entity, stringBuilder);
}
}
The class where all the test scenarios are described is MockClass.java
@RunWith(PowerMockRunner.class)
@PrepareForTest({Helper.class,ExternalHelper.class})
public class MockClass {
Entity entity;
StringBuilder stringBuilder;
@Before
public void init()
{
entity = new Entity();
entity.setBenefitDate(new Date(new java.util.Date().getTime()));
stringBuilder = new StringBuilder();
}
..............
................
.....................
For using Powermock, we need to annotate the test class with PowerMockRunner.class and the classes to be mocked should be specified in @PrepareForTest annotation. The @PrepareForTest annotation can be specified at both class and method level. This annotation should include classes whose bytecode needed to be transformed i.e.final classes, classes with final, private, static or native methods that should be mocked and also classes that should be return a mock object upon instantiation.
Since a Test class cannot have more than One Runner, situations when a Test Class needs to be annotated with a different runner and the Test Cases should also include mocking then we could use public @Rule PowerMockRule rule = new PowerMockRule() instead of PowerMockRunner and use the required Runner in its place.
No Lets get into the scenarios one by one.
NEXT
Thursday, 5 March 2015
A Brief rendezvous with Spock (Part II)
FEATURE METHOD
The feature method is somewhat similar to @Test annotated methods in JUnit. Here, all the test related jobs are being done but in a different way as its body consists of the following logical blocks: a) setup b) when c) then d) expect e) cleanup and f) where Now, let’s describe each of these blocks with reference to the below mentioned code block, so that it becomes easy to understand
HELPER METHODS
Sometimes the common code blocks in feature methods are separated out from and Helper Methods are created from them to avoid redundancy. So this is in short my introduction with Spock. Hope this post would bring some purpose to readers. Any suggestions and feedback are always welcome. Please share your view and Keep coding……..
The feature method is somewhat similar to @Test annotated methods in JUnit. Here, all the test related jobs are being done but in a different way as its body consists of the following logical blocks: a) setup b) when c) then d) expect e) cleanup and f) where Now, let’s describe each of these blocks with reference to the below mentioned code block, so that it becomes easy to understand
def "Second Test2"()
{
setup: "Initialize variables here"
println "***** Variables Initialized *******"
when: "Call Operations to be executed"
println "Operations invokded"
then: "Compare Actual Result with Expected one"
println "${param1}<--->${param2}"
cleanup: "CleanUp Things"
println "*** CleanUp Done **** "
where:
param1 | param2
'ok1' | "asd|asd|||tgh||ASD"
'ok9909'| "asd|asd|||990||ASD"
}
Now from the above mentioned code block, it becomes quite evident that the name of the Feature Method is a user-defined one which has been provided in quotes after def i.e. “Second Test2”, So we should always try to provide a meaningful name to the Feature Methods.
Each feature method must have atleast one explicit block and the blocks should not be nested.
a) setup
In this block all the initialization and declarations, which needs to be done before each tests are placed. It is similar to given: block.b) when & c) then
Basically the when: and then: blocks appear in pairs and there may be multiple appearances of them in the feature methods. In the when: block we excute the code block which needs to be tested and in the then: block, we compare the output the when: block method call (i.e. actual Result) with the expected Result. Please note that the conditions are written in plain Boolean expressions so there is no need of using any Assertion statements. There are multiple tools to handle exceptions in the then: block like:thrown(MyCustomException) or def e = thrown(MyCustomException) or MyCustomException e = thrown()Sometimes we don't want exceptions to be thrown out, then we could go for:
notThrown(MyCustomException)
d) expect
expect: block is used when we want to club both when: and then: in a single expression.e) cleanup
From the name it is quite evident, resource cleanup activities may be done here.f) where:
It is used to create a Data-Driven feature methods, like we have used in the above code snippet to create a parameterized test cases, and it is usually comes last in the feature method. The block defined in the feature methods presents us with a BDD i.e. Behaviour Driven Design. The last component in the specification is:HELPER METHODS
Sometimes the common code blocks in feature methods are separated out from and Helper Methods are created from them to avoid redundancy. So this is in short my introduction with Spock. Hope this post would bring some purpose to readers. Any suggestions and feedback are always welcome. Please share your view and Keep coding……..
A Brief rendezvous with Spock
This post is only such an honest attempt to share my short but effective experience with Spock.
The testing class should extend “Specification” class which belongs to the spock.lang.* package.
Lets, go through the structure of a Spock Specification class.
FIELDS
Initializing objects into instance fields which may be used up in further proceedings (in feature methods) can be done here. One important thing to look out for is that, objects which are stored in instance fields are not shared among the feature methods, each feature methods gets their own copies, this thing makes the feature methods stateless and isolate them from each other. Now, if we want to make a field to be shared between feature methods, then we could use the annotation @Shared or use the keyword static. The static should always be used in case of constants.
FIXTURE METHODS
The Fixture Methods are like the lifecycle methods of Specification. There are four Fixture Methods. They are as follows:
class SpockParameterized extends Specification{
def numberA
def numberB
Here the class SpockParameterized extends Specification . The Class Specification instructs JUnit to run the specification i.e. the test class with Spock’s JUnit runner, SPUTNIK.
A Specification structure consists of the following components:
class SpockParameterized extends Specification{
//fields
//fixture methods
//feature methods
//helper methods
}
I will try to provide a little detailing on each of the above mentioned components.FIELDS
Initializing objects into instance fields which may be used up in further proceedings (in feature methods) can be done here. One important thing to look out for is that, objects which are stored in instance fields are not shared among the feature methods, each feature methods gets their own copies, this thing makes the feature methods stateless and isolate them from each other. Now, if we want to make a field to be shared between feature methods, then we could use the annotation @Shared or use the keyword static. The static should always be used in case of constants.
FIXTURE METHODS
The Fixture Methods are like the lifecycle methods of Specification. There are four Fixture Methods. They are as follows:
def setupSpec()
{
}
This is similar to static methods annotated with @BeforeClass in JUnit.
def cleanupSpec()
{
}
This is similar to static methods annotated with @AfterClass in JUnit.
def setup()
{
}
This is similar to static methods annotated with @Before in JUnit.
def cleanup()
{
}
This is similar to static methods annotated with @After in JUnit.
So the Fixture Method part is clear.
NEXT
JUnit Parameterized Test Cases with Groovy
Lets traverse through the code first:
@RunWith(Enclosed)
class ParameterizedTest{
@BeforeClass
static void init()
{
System.out.println(" Setup Class Wide Accessible Resources Here")
}
@AfterClass
static void release()
{
System.out.println(" Release Class Wide Accessible Resources after all the tests are successfully completed")
}
@RunWith(Parameterized)
static class TestLogon{
def numberA
def numberB
TestLogon( numA, numB) {
numberA = numA
numberB = numB
}
@Parameters static data1() {
[
[null, "asd|asd|||ASD||ASD"],
['09909', "asd|asd|||ASD||ASD"]
]*.toArray()
}
@Test
void testLogonRequest1() throws Exception {
println numberA+":"+numberB
}
@Test
void testLogonRequest2() throws Exception {
println "Dummy Tests method to test @Before and @After annotated methods"
}
@Before
void initTestLogon()
{
println "Intialize Configuration which is to be done before each test methods"
}
@After
void releaseTestLogon()
{
println "Release Configuration which is to be done after each test methods"
}
}
@RunWith(Parameterized)
static class TestLogon2{
def numberA
def numberB
TestLogon2( numA, numB) {
numberA = numA
numberB = numB
}
@Parameters static data2() {
[
[ "1", "asd111|asd99|||ASD990||ASD9897"]
]*.toArray()
}
@Test
void testLogonRequest() throws Exception {
println numberA+":"+numberB
}
}
@RunWith(Parameterized)
static class TestLogon3{
def numberA
def numberB
TestLogon3( numA, numB) {
numberA = numA
numberB = numB
}
@Parameters static data2() {
[
[ "999", "asd111|asd99|||ASD990||ASD9897"]
]*.toArray()
}
@Test
void testLogonRequest() throws Exception {
println numberA+":"+numberB
}
}
}
The output of the above code snippet is:
Setup Class Wide Accessible Resources Here Intialize Configuration which is to be done before each test methods null:asd|asd|||ASD||ASD Release Configuration which is to be done after each test methods Intialize Configuration which is to be done before each test methods Dummy Tests method to test @Before and @After annotated methods Release Configuration which is to be done after each test methods Intialize Configuration which is to be done before each test methods 09909:asd|asd|||ASD||ASD Release Configuration which is to be done after each test methods Intialize Configuration which is to be done before each test methods Dummy Tests method to test @Before and @After annotated methods Release Configuration which is to be done after each test methods 1:asd111|asd99|||ASD990||ASD9897 999:asd111|asd99|||ASD990||ASD9897 Release Class Wide Accessible Resources after all the tests are successfully completedThe main thing I want to point out in the above code snippet is the @Parameters annotated data methods. The parameters are all provided in a 2D array format and toArray() is called using spread(*) operator instead of calling toArray() on each of the array and thus avoiding redundancy i.e.
[
[null, "asd|asd|||ASD||ASD"],
['09909', "asd|asd|||ASD||ASD"]
]*.toArray()
instead of
[
[null, "asd|asd|||ASD||ASD"].toArray(),
['09909', "asd|asd|||ASD||ASD"].toArray()
]
Interesting right....
Like this there are loads of Groovy features, which are really mindblowing, I will try to share those in a separate post.
Please share your views and ideas and Till Next time Keep Coding......
Sunday, 1 March 2015
Hamcrest with a Custom Touch (Part III)
Now, there could arise a situation, where we need to have a matcher, which clubs different matchers, kind of like a Composite Matcher.
The idea is not clear right, lets traverse the code.......
public class CompositeMatcher extends BaseMatcher{
static List matcherAndList = new ArrayList();
static List failedMatcherList = new ArrayList();
public CompositeMatcher and(final Matcher matcher)
{
matcherAndList.add(matcher);
return this;
}
public CompositeMatcher(final Matcher matcher)
{
matcherAndList.add(matcher);
}
@Override
public void describeTo(final Description description) {
description.appendText("expected result from CompositeMatcher(): ")
.appendValue(description);
}
@Override
public boolean matches(final Object item) {
System.out.println(" ***** Matcher List is:"+matcherAndList+"\n Size()"+matcherAndList.size());
System.out.println(" ***** The item to be matches is:"+item);
for(Matcher matcher : matcherAndList)
{
if(! matcher.matches(item))
return false;
}
return true;
}
@Override
public void describeMismatch(final Object item,
final Description mismatchDescription) {
mismatchDescription.appendText("was ").appendValue(
item);
}
public static CompositeMatcher all(Matcher matcher)
{
return new CompositeMatcher(matcher);
}
}
and its usage will be:
assertThat(person1, all(hasName("Subha")).and(hasAddress("KOLKATA")));
Where person1 is of type Person.
Now, the matcher we could see here is:
1)hasName
2)hasAddress
3)all
4)and
We are already acquainted with hasName and hasAddress matcher.
Lets go for all & and matchers
If we see the definition of all in CompositeMatcher.java, we could see that it returns a new Object of type CompositeMatcher (taking the matcher as its parameter) and the constructor stores the matcher in the List.
Similarly for and matcher takes a matcher as parameter, stores that matcher in the List and returns the current Object.
The interesting thing to notice here is that, all the matchers are being stored in some DataStructure so that they could be invoked later and return type being CustomMatcher which extends org.hamcrest.BaseMatcher so that if we need another matcher we could do so by using:
assertThat(person1, all(hasName("Subha")).and(hasAddress("KOLKATA")).add(<<put another Matcher here>>));
by this way we can extend the chain. All the matchers are being stored in a Class Level List.
When the above assertThat is executed, then matches() of the CompositeMatcher.java gets called, and it does the MAGIC.....
So, this is in short an introduction to Hamcrest. Any suggestions or opinions are always welcome.
Please share your views.
Hamcrest with a Custom Touch (Part II)
For Custom Matchers of a each of the above beans TypeSafeMatcher is being used, which takes the Type to be matched as the parameter, hence Type Safety is guranteed, hence no possible cases of ClassCastException could arise.
The AddressMatcher.java
public class AddressMatcher {
public static Matcher equalTo(final Address expectedAddress)
{
return new TypeSafeMatcher() {
@Override
public void describeTo(final Description description) {
description.appendText("expected result from getIsbn(): ")
.appendValue(expectedAddress);
}
@Override
public boolean matchesSafely(final Address actualAddress) {
return actualAddress.getHouseNo().equals(expectedAddress.getHouseNo()) && actualAddress.getLocality().equals(expectedAddress.getLocality()) && actualAddress.getCity().equals(expectedAddress.getCity()) ;
}
@Override
public void describeMismatchSafely(final Address address,
final Description mismatchDescription) {
mismatchDescription.appendText("was ").appendValue(
address);
}
};
}
}
In the AddressMatcher.java, the we have provided an implementation of the equalTo() matcher.
The PersonMatcher.java
public class PersonMatcher {
public static Matcher equalTo(final Person expectedPerson)
{
return new TypeSafeMatcher() {
@Override
public void describeTo(final Description description) {
description.appendText("expected result from getIsbn(): ")
.appendValue(expectedPerson);
}
@Override
public boolean matchesSafely(final Person actualPerson) {
return actualPerson.getSsn() == expectedPerson.getSsn();
}
@Override
public void describeMismatchSafely(final Person person,
final Description mismatchDescription) {
mismatchDescription.appendText("was ").appendValue(
person);
}
};
}
public static Matcher hasName(final String expectedPersonName)
{
System.out.println(" **** In HasName **** ");
return new TypeSafeMatcher() {
@Override
public void describeTo(final Description description) {
description.appendText("expected result from hasName(): ")
.appendValue(expectedPersonName);
}
@Override
public boolean matchesSafely(final Person actualPerson) {
return actualPerson.getName().equals(expectedPersonName);
}
@Override
public void describeMismatchSafely(final Person person,
final Description mismatchDescription) {
mismatchDescription.appendText("was ").appendValue(
person.getName());
}
};
}
public static Matcher hasAddress(final String expectedAddress)
{
System.out.println(" **** In hasAddress **** ");
return new TypeSafeMatcher() {
@Override
public void describeTo(final Description description) {
description.appendText("expected result from hasAddress(): ")
.appendValue(expectedAddress);
}
@Override
public boolean matchesSafely(final Person actualPerson) {
return actualPerson.getAddress().getCity().equalsIgnoreCase(expectedAddress);
}
@Override
public void describeMismatchSafely(final Person person,
final Description mismatchDescription) {
mismatchDescription.appendText("was ").appendValue(
person.getName());
}
};
}
}
In the PersonMatcher.java, we have provided equalTo(), hasName() and hasAddress() matchers.
The CompanyMatcher.java
public class CompanyMatcher {
public static Matcher hasCompanyName(final String expectedCompanyName)
{
return new TypeSafeMatcher() {
@Override
public void describeTo(final Description description) {
description.appendText("expected result from getIsbn(): ")
.appendValue(expectedCompanyName);
}
@Override
public boolean matchesSafely(final Company actualCompany) {
return actualCompany.getName().equals(expectedCompanyName);
}
@Override
public void describeMismatchSafely(final Company company,
final Description mismatchDescription) {
mismatchDescription.appendText("was ").appendValue(
company.getName());
}
};
}
}
Similarly in the CompanyMatcher.java, there is hasCompanyName() matcher.
So this is in short about Custom Hamcrest Matcher.
NEXT
Hamcrest with a Custom Touch
The usage of assertThat can be described as:
assertThat(thePerson, equalTo(myPerson));Here, the subject of the assertion is the object thePerson that is the first method parameter. The second method parameter is a matcher for Person objects, here a matcher "equalTo" that checks one object is equal to another using the Object equals method, i.e. thePerson is equal to myPerson. Here let's assume, thePerson and myPerson are of Person type, and it overrides Object's equal method. Like "equalTo" there are other matchers defined by Hamcrest, they can be found at Hamcrest Matchers The main aim of Hamcrest is to make the Tests as readable as poosible.One such attepmt is "is" matcher.
assertThat(thePerson, is(equalTo(myPerson)));is matcher is a wrapper that doesn't add any extra behavior to the underlying matcher. The following assertions are all equivalent:
assertThat(thePerson, is(equalTo(myPerson))); assertThat(thePerson, equalTo(myPerson)); assertThat(thePerson, is(myPerson));The main power of Hamcrest lies in defining the Custom Matchers. Often we need to define more than one Custom Matchers and to use them in our Unit Tests, we need to statically import the indivudually. But there lies a consolidated approach for the same. An XML configuration file listing all the Matcher classes that should be searched for factory methods annotated with the org.hamcrest.Factory annotation.
<matchers> <!-- Custom extension 1 --> <factory class="com.action.hamcrest.AddressMatcher"/> <!-- Custom extension 2 --> <factory class="com.action.hamcrest.PersonMatcher"/> </matchers>The org.hamcrest.generator.config.XmlConfigurator command-line tool that comes with Hamcrest needs to be executed, which takes the XML configuration file and generates a single Java class that includes all the factory methods specified by the XML file. Running it with no arguments will display a usage message. Now let's traverse through the Custom Matchers. Here we have created 3 bean classes, they are: Address.class
public class Address {
private String houseNo;
private String street;
private String locality;
private String city;
private String state;
private int zipcode;
public String getHouseNo() {
return houseNo;
}
/**
* Other getter/setters, toString(), hashCode() and equals() method
*
*/
Person.class
public class Person {
private String name;
private Address address;
private Long ssn;
public String getName() {
return name;
}
/**
* Other getter/setters, toString(), hashCode() and equals() method
*
*/
Company.class
public class Company {
private String name;
private Address address;
private Set employee;
public String getName() {
return name;
}
/**
* Other getter/setters, toString(), hashCode() and equals() method
*
*/
NEXT
Confab with Testing frameworks for Compelling lineaments
This time I am going to stress upon some TESTING approaches, which we often follow, while creating unit tests cases of our code. Creating Unit Tests of our code is one of the most important phases of the Software Development Life Cycle and so the test cases should be created in such a way that our functionality gets properly tested with all possible path flows.
Now, for testing purposes the most common and widely used Testing Framework in Java is JUnit. Its seamless integration with different Java Based Frameworks especially Spring (with the help of different RUNNERS) makes it a DEARIE. One of the ineresting and useful feature of Junit Tests is the Parameterized way of Testing.
While during JUnit Testing, we compare the expected result with the actual result using different Assert statements, which matches actual result with the expected result. Hamcrest is a framework for writing matcher objects allowing 'match' rules to be defined declaratively.
The assertThat method is a stylized sentence for making a test assertion.
Here is a brief discussion on the topic.
Recently, I am trying to learn Groovy features. So, decided to transform the JUnit Parameterized Test Cases to Groovy and after transformation I found it really interesting. Groovy with all its dynamicity and lot of resourceful operators is really interesting.Let's find it out.
Recently, I am having my first encounter with Groovy, I am learning it and Groovy with its loads of mind blowing features does gives me a lot of interest, & I will share my experience with Groovy in a separate link.
Here, all I wanted to part is my confab with Spock, a testing framework for Groovy. While using it, I have really become a fan of it , believe me and you would too become so once to get acquainted with it.
Mocking is a important feature while doing unit Testing. Now the question arises what is mocking and why should we use mocking?
While doing unit Testing, we often come across scenarios where we find that our code is dependent on some third party implementation or some other functionalities which are actually not a part of the block of code to be unit tested, so most often we would like to mimic or mock those features so that we could proceed on with our Test cases.
Mocking with PowerMock is indeed a powerful feature. Recently while I was testing a class that has got some dependent objects autowired in it(Spring),
I thought of using some features other than PowerMock, then I came to know of the following.
JUnit Parameterized Test with Enclosed behaviour
In this post We will be discussing that.
Recently, I came across a requirement where there are multiple functionalities present as separate methods enclosed in a single class. The class is a kind of Utililty class type and I need to create Test each of its methods with all possible input types to judge the integrity of each of the functionalities of the class. So, what I came up with approach to create JUnit Parameterized Classes of each of the functionalities, but the problem is that, there are too many JUnit Parameterized Classes are getting created as there are lots of util methods in the class. So, I need to find a way to try to consolidate all the Test Cases in a Single class.
I decided to create Inner classes for testing (in a Parameterized way) each of the functionalities and enclose all of them in a Outer class.
org.junit.experimental.runners.Enclosed provided me the control that I needed.
Let's go through the Code:
@RunWith(Enclosed.class)
public class ParameterizedTest{
@BeforeClass
public static void init()
{
System.out.println(" Setup Class Wide Accessible Resources Here");
}
@AfterClass
public static void release()
{
System.out.println(" Release Class Wide Accessible Resources after all the tests are successfully completed");
}
@RunWith(value=Parameterized.class)
public static class TestLogon{
private String numberA;
private String numberB;
public TestLogon(String numberA, String numberB) {
this.numberA = numberA;
this.numberB = numberB;
}
@Parameterized.Parameters
public static Iterable
The output is:
Setup Class Wide Accessible Resources Here Intialize Configuration which is to be done before each test methods null:asd|asd|||ASD||ASD Release Configuration which is to be done after each test methods Intialize Configuration which is to be done before each test methods Dummy Tests method to test @Before and @After annotated methods Release Configuration which is to be done after each test methods 1:asd111|asd99|||ASD990||ASD9897 999:asd111|asd99|||ASD990||ASD9897 Release Class Wide Accessible Resources after all the tests are successfully completedFrom the output it is quite apparent, the order of execution of the code and the various lifecycle methods of JUnit. Please note that @Before and @After annotated methods we have used with TestLogon, but it could also be implemented in other Inner Classes too. I am not describing how the Parameterized Test Cases work for JUnit as there are lots of good descriptive resources available. Hope this post provides you some help. Any suggestions or opinions are always welcome. Please share your views. Keep Coding ang Keep sharing.....
Subscribe to:
Comments (Atom)