1

In a pure Java module, I have a dependency to compile group: 'org.threeten', name: 'threetenbp', version: threeTenVersion, classifier: 'no-tzdb'. I'm using the no-tzdb variant because this module will be used inside an Android app and the the tzdb will be added by the Android module.

However, in my unit tests, I would like to be able to call some methods like DateTime.now() which requires ThreeTen to be initializd with a tzdb.

I would like to know if there is a way to use another version of the library only during unit tests so that I can use the version with the tzdb installed ?

I already tried the following :

compile group: 'org.threeten', name: 'threetenbp', version: threeTenVersion, classifier: 'no-tzdb'
    testCompile "org.threeten:threetenbp:threeTenVersion"

But the no-tzdb is still used.

Thank you, Pierre

pdegand59
  • 12,776
  • 8
  • 51
  • 58
  • Have you tried marking threeTen for your tests as 'testRuntime'? See the [following](https://docs.gradle.org/current/userguide/artifact_dependencies_tutorial.html) – DivDiff Oct 20 '16 at 20:57
  • Actually it just works the way I tried, it was just Android Studio that was not understanding the new testCompile line I added to the build script. I restarted the IDE and it runned perfectly ... Strange ... Thank you anyway – pdegand59 Oct 21 '16 at 08:28
  • also, you can build a tzdb only jar that you can add to your testCompile config: http://www.threeten.org/threetenbp/update-tzdb.html – RaGe Oct 21 '16 at 13:14
  • Yeah gradle can be finicky like that. I seem to remember running into this issue in the past. What IDE do you use? – DivDiff Oct 21 '16 at 13:35

2 Answers2

1

Not sure if this is relevant in your case, but one approach to consider:

  1. If you're not already using ThreeTenABP (ThreeTen Android Backport), which efficiently initialises timezone information on Android, switch to using it.
  2. In your unit tests, use the original JVM backport (threetenbp).

I was inspired by https://github.com/JakeWharton/ThreeTenABP/issues/14 to try the JVM backport in tests, and it works for me.

So in build.gradle I have:

compile 'com.jakewharton.threetenabp:threetenabp:1.0.4' 

// For unit tests involving ThreeTen, use JVM backport instead of Android one
testCompile('org.threeten:threetenbp:1.3.3') {
    exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
}

With this setup, in my unit tests, methods like ZonedDateTime.now() and OffsetDateTime.now() work fine. (There is no type called DateTime in ThreeTen.)

Jonik
  • 80,077
  • 70
  • 264
  • 372
0

If you're using Mockito, you can mock a Context and AssetManager so AndroidThreeTen loads your test project's version of TZDB.dat. Something like:

@Before
public void setUp() throws Exception {
    Context mockContext = mock(Context.class);
    AssetManager mockAssets = mock(AssetManager.class);
    when(mockAssets.open(anyString())).thenReturn(getClass().getClassLoader().getResourceAsStream("TZDB.dat"));
    when(mockContext.getAssets()).thenReturn(mockAssets);
    AndroidThreeTen.init(mockContext);
}

Make sure to put your TZDB.dat in src/test/resources/TZDB.dat

If you're looking for TZDB.dat it can be found here after you've built your project: project_directory/app/build/intermediates/exploded-aar/com.jakewharton.threetenabp/threetenabp/1.0.4/assets/org/threeten/bp/TZDB.dat