Tuesday, November 27, 2007

How to restore a tab which has just closed in Firefox?

Just closed a Firefox's tab unfortunately? There is a solution for it, you can use Ctrl + Shift + T to restore the tab.

And even more suprise, if your text box contains text, it will not be lost :-)

Monday, November 19, 2007

How to call EasyMock.verify() when you expect an exception in TestNG

I have this test which is written in JUnit
public void testConvertWithUnknownCurrency()
throws UnknownCurrencyException {
EasyMock.expect(
exchangeRateService.getExchangeRate(
EasyMock.isA(String.class),
EasyMock.isA(String.class)
)
).andThrow(new UnknownCurrencyException());

EasyMock.replay(exchangeRateService);

try {
converter.convert(10.0, "EUR", "-UNKNOWN-");
fail("an unknown currency exception was expected");
} catch (UnknownCurrencyException e) {
// do nothing, was expected
}

EasyMock.verify(exchangeRateService);
}

I converted it to use TestNG as below
@Test(expectedExceptions = {UnknownCurrencyException.class})
public void testConvertWithUnknownCurrency() {
EasyMock.expect(
exchangeRateService.getExchangeRate(
EasyMock.isA(String.class),
EasyMock.isA(String.class)
)
).andThrow(new UnknownCurrencyException());

EasyMock.replay(exchangeRateService);

converter.convert(10.0, "EUR", "-UNKNOWN-");

EasyMock.verify(exchangeRateService);
}

then found that EasyMock.verify(exchangeRateService) will never be called 'cause converter.convert(10.0, "EUR", "-UNKNOWN-") throws UnknownCurrencyException. So how to make the test works as same as JUnit version?

Spend more time to read TestNG document and search in TestNG forum, I found that I can use @Test's dependsOnMethods attribute. But note that TestNG supports 2 kinds of dependencies: hard and soft. And here is explaination from TestNG document:

* Hard dependencies. All the methods you depend on must have run and succeeded for you to run. If at least one failure occurred in your dependencies, you will not be invoked and marked as a SKIP in the report.
* Soft dependencies. You will always be run after the methods you depend on, even if some of them have failed. This is useful when you just want to make sure that your test methods are run in a certain order but their success doesn't really depend on the success of others. A soft dependency is obtained by adding "alwaysRun=true" in your @Test annotation.

Now I have a clear understanding about dependsOnMethods, what I need is a soft dependency. And here is TestNG version of above test.
@Test(expectedExceptions = {UnknownCurrencyException.class})
public void testConvertWithUnknownCurrency() {
EasyMock.expect(
exchangeRateService.getExchangeRate(
EasyMock.isA(String.class),
EasyMock.isA(String.class)
)
).andThrow(new UnknownCurrencyException());

EasyMock.replay(exchangeRateService);

converter.convert(10.0, "EUR", "-UNKNOWN-");
}

@Test(alwaysRun = true,
dependsOnMethods = "testConvertWithUnknownCurrency")
public void verifyAfterTestConvertWithUnknownCurrency() {
EasyMock.verify(exchangeRateService);
}

The test works as expected. Smile :-)

Updated: Re-think about my TestNG test version, I will remove alwaysRun = true from verifyAfterTestConvertWithUnknownCurrency(). Why? 'Cause if testConvertWithUnknownCurrency() fails, it means the test fail, don't need to waste my time to verify something it was failed.

One reason to use dependent methods 'cause it makes the test clearly. I know exactly where the test fails, 'cause it doesn't throw exception or 'cause EasyMock.verify() fails.

Sunday, November 18, 2007

Thursday, November 15, 2007

Custom or Standard?

Modern languages like Java, C#,... provide powerful APIs with many libraries which are ready to use. But sometimes I consider I should use the "standard" class or create my own custom class. Spending more time to think about it, I realize that it depends.

Assumes that I want to have a list of members, if I use Java, I can use List<Member> or create my own MemberList to store all members. If I want to have more features than the standard List<Member> provides, of course, I need to create my own MemberList, which bases on List<Member>. But what will I do if I only need a read-only list? A List<Member> cannot do it. To have a read-only list, I need to use Collections.unmodifiableList(myMemberList) or create MemberList which supports read-only only.

Now consider that I only need to use the read-only list inside my application, which solution can I choose? One of two but maybe one of three. I also can use List<Member> and forget about its "edit" methods.

To have a clearer design, using MemberList will be the best solution but it needs time to implement. To be lazy, using Collections.unmodifiableList(myMemberList) or List<Member> without using its "edit" methods is an acceptable answer.

Wednesday, November 14, 2007

The rest books

Today, I received the last 2 books for my order from Amazon. They came earlier than the estimation 3 days :-)

Too many books to read, too much works to do :-)

Tuesday, November 13, 2007

Monday, November 12, 2007

The first delivery

Even though I chose to pack all items in one package but Amazon delivered my order in 2 separate ones. And I've just received the first package, it contains 3 books

Amazon estimated my first package will be delivered from Nov 12 to Nov 20. And today, I received it. Their service works exactly :-)

The second one will be here from Nov 17 to Nov 30. Then I will spend more time for reading about testing.

FYI: Spring 2.5 supports to test by TestNG (and JUnit 4)

Sunday, November 11, 2007

The weekly bag - Nov. 11