How to unit test monetary conversion?
mickaeltr opened this issue · 6 comments
Hello,
I was wondering what you would suggest for unit testing monetary conversion?
What I would expect from a unit test is:
- to be repeatable (fixed currency rate?)
- to work with no internet connection
That would be a great addition to the documentation.
Thanks
To be more precise, I have a function that sums EUR and GBP (converted to EUR) amounts and I want to assert that the final sum is as expected (hence that the conversion was made accordingly).
I don't think that's really something for the RI. And I don't recall a "Guidebook" or @otaviojava do you know one? To contribute here one must be a JCP member, but I don't see @mickaeltr that you are a JCP Member yet, are you?
It's free, but of course for this purpose alone you don't have to join @mickaeltr unless you have intentions beyond that? I struggle to find the right place. I remember @otaviojava once had a javamoney-book but it did not seem very active lately. It seems a kind of tutorial or examples, under certain circumstances it could also be good for javamoney-examples, both do not require JCP membership.
A quick update on this topic.
The best I managed to do was to disable most of the exchange rate providers, with the following javamoney.properties
in my test resources:
load.ECBCurrentRateProvider.startRemote=false
load.ECBCurrentRateProvider.type=NEVER
load.ECBHistoric90RateProvider.startRemote=false
load.ECBHistoric90RateProvider.type=NEVER
load.ECBHistoricRateProvider.startRemote=false
load.ECBHistoricRateProvider.type=NEVER
load.IMFHistoricRateProvider.startRemote=false
load.IMFHistoricRateProvider.type=NEVER
load.IMFRateProvider.startRemote=false
load.IMFRateProvider.type=NEVER
For some reason it still does some remote calls and I could not setup a fixed exchange rate. So I isolated the code responsible for converting currency:
public MonetaryAmount convertTo(MonetaryAmount money, CurrencyUnit unit) {
// That makes remote calls to fetch exchange rates
var conversion = MonetaryConversions.getConversion(unit);
return money.with(conversion);
}
… and added a fuzzy unit test:
// Beware that this test is not strictly isolated because it makes remote calls to fetch exchange rates
@Test
void should_convert_gbp_to_eur() {
// Given
var gbp = Money.of(1, Monetary.getCurrency("GBP"));
// When
var eur = currencyRepository.convertTo(gbp, Monetary.getCurrency("EUR"));
// Then
Assertions.assertThat(eur.getNumber().doubleValue())
// Using a range because exchange rate is not fixed
.isGreaterThan(1)
.isLessThan(2);
}
That is not perfect but acceptable to me right now. So I am closing this issue. Thanks
@mickaeltr Thanks a lot for the update. Glad you found a working solution.
Especially about disabling some would you be interested and able to write about it somewhere?
Either in our Blog-like update section: http://javamoney.github.io/archive.html (I know the name "archive" may sound misleading, but no time to change a running system right now) or somewhere else, e.g. we could activate the "Wiki" here, too if it works better?