square/assertj-android

Unable to import static method assertThat

plackemacher opened this issue · 32 comments

I replaced the line in my build.gradle file that declared using Fest-Android with one for AssertJ-Android:

-    androidTestCompile('com.squareup:fest-android:1.0.+') {
+    androidTestCompile('com.squareup.assertj:assertj-android:1.0.0') {

The issue is that after replacing all static imports of import static org.fest.assertions.api.ANDROID.assertThat; with import static org.assertj.android.api.Assertions.assertThat;, the static import isn't found therefore my Robolectric tests fail to compile. If I change the Gradle line to use compile instead of androidTestCompile, the tests work correctly but obviously that's not optimal nor what the documentation describes.

The error returned by javac is the following:

File.java:∞ error: package org.assertj.android.api does not exist
import static org.assertj.android.api.Assertions.assertThat;
                                     ^
emce commented

Same to me - I can just import basic import static org.assertj.core.api.Assertions.assertThat;

Me too. What configurations you re using? Can u attach build.gradle?

Mine

buildscript {
--//--
  dependencies {
    classpath 'com.android.tools.build:gradle:0.12.2'
    classpath 'com.github.jcandksolutions.gradle:android-unit-test:1.2.3'
    --//--
  }
}

apply plugin: 'com.android.application'

--/android section/--

apply plugin: 'android-unit-test'

dependencies {
  compile 'com.android.support:support-v4:20.0.0'
  compile 'com.android.support:support-annotations:20.0.0'

--//--

  testCompile 'junit:junit:4.10'
  testCompile 'org.robolectric:robolectric:2.3'
  testCompile 'com.squareup.assertj:assertj-android:1.0.0'
}
emce commented
    androidTestCompile('junit:junit:4.11') {
        exclude module: 'hamcrest-core'
    }
    androidTestCompile('org.robolectric:robolectric:2.3') {
        exclude module: 'classworlds'
        exclude module: 'commons-logging'
        exclude module: 'httpclient'
        exclude module: 'maven-artifact'
        exclude module: 'maven-artifact-manager'
        exclude module: 'maven-error-diagnostics'
        exclude module: 'maven-model'
        exclude module: 'maven-project'
        exclude module: 'maven-settings'
        exclude module: 'plexus-container-default'
        exclude module: 'plexus-interpolation'
        exclude module: 'plexus-utils'
        exclude module: 'support-v4'
        exclude module: 'wagon-file'
        exclude module: 'wagon-http-lightweight'
        exclude module: 'wagon-provider-api'
    }
    androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'
    androidTestCompile 'com.squareup.assertj:assertj-android-support-v4:1.0.0'
    androidTestCompile 'com.squareup.assertj:assertj-android-appcompat-v7:1.0.0'
    androidTestCompile 'com.squareup.assertj:assertj-android-play-services:1.0.0' 

I doesn't work for me either. I made a seperate module for my roboelectric tests so I could apply the normal gradle java plugin but I doesn't work in there. (not able to find the static imports). Not as compile and not as testCompile.

When I put it down as androidTestCompile (or compile)-dependency in my app module it works, but I'd love it if this would also work with the normal java plugin and testCompile.

(I'm not sure if the root of my issue is similair to this issue but the consequences are the same: static import fails - although, he doesn't find the android part for me either)

The same issue here:

Able to find static import:
compile 'com.squareup.assertj:assertj-android:1.0.0'

Not able to find static import:
androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'

Same problem here, when I run Robolectric tests it doesn't find static import with "androidTestCompile", but it does with just "compile".

@JakeWharton, would I be correct in assuming you haven't run across this?

I have with other libraries. Pretty sure it's just a build system / IDE integration bug.

what's the difference between assertJ and fest asset BTW?

assertj is a fork of fest, which is no longer maintained I believe.

Same issue here, AS finds the import fine, but the android package is not found when compiling the test code from command line.

getting the same error here, on this project https://github.com/mutexkid/android-studio-robolectric-example
when i try to switch it over to use assertj instead of fest. I only changed :

 dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.10'
        androidTestCompile 'org.robolectric:robolectric:2.3'
        androidTestCompile 'com.squareup:fest-android:1.0.8'
    }

to :

dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.10'
        androidTestCompile 'org.robolectric:robolectric:2.3'
        androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'
    }

and updated the static import to use assertJ.

error: package org.assertj.android.api does not exist
import static org.assertj.android.api.Assertions.assertThat;

Is there a reason assertj-android is an AAR? If I strip the classes.jar from it, everything resolves fine.

Future-proofing. Maybe we want to ship custom lint rules in the future.
On Oct 1, 2014 9:52 AM, "Ron Shapiro" notifications@github.com wrote:

Is there a reason assertj-android is an AAR? If I strip the classes.jar
from it, everything resolves fine.


Reply to this email directly or view it on GitHub
#129 (comment)
.

Any progress on this? I am setting up Robolectric in its own module, therefore I need testCompile instead of androidTestCompile since it's a java module.

Same issue here. Using Android Studio 0.8.10 and 0.8.11.

Same thing here in AS 0.8.9. Temporary solution: compile with 1.0.0

testCompile('com.squareup:fest-android:1.0.0')

👍 on the problem. AS seems to be ok, gradle on the command line is not. Odd thing, I can't find the library listed in External Libraries so I'm not sure how AS is making it work.

A temporary solution:

androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'
// TODO: remove this when https://github.com/robolectric/robolectric-gradle-plugin/pull/87 is released
androidTestCompile project.files("$project.buildDir/intermediates/exploded-aar/com.squareup.assertj/assertj-android/1.0.0/classes.jar")

👍 to future-proofing.

Finally it works with latest robolectric plugin!

I could only get it to work with the following in Android Studio RC 4.

compile 'org.assertj:assertj-core:1.7.0'
androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'

I'm using the standard android testing library and not Robolectric

Not a preferred approach as this will include assertj-core in your app build, but it works.

@JakeWharton is correct that it was a bug with the Gradle build system. It has been fixed (as of a couple weeks ago) so make sure you're using the latest version of Android build tools and Gradle plugins. Closing.

@plackemacher I see that the classpath is built correctly to reference the exploded-aar path to the jar file, but the path has not been exploded when running ./gradlew :compileTestDebugJava, so the path is not accessible, and the classes are not available to the compile task (same as the original issue). What exactly needs to be updated to get the fix that you referenced?

I'm using buildToolsVersion 21.1.2, 'com.android.tools.build:gradle:1.0.0', 'org.robolectric:robolectric-gradle-plugin:0.14.1', and testCompile 'com.squareup.assertj:assertj-android:1.0.0'. Printing:

println "classpath: " + project.tasks.compileTestDebugJava.classpath.files

shows the path to the classes.jar: <projectRoot>/build/intermediates/exploded-aar/com.squareup.assertj/assertj-android/1.0.0/classes.jar, but:

$ ls -l build/intermediates/exploded-aar/com.squareup.assertj/assertj-android/1.0.0/classes.jar
ls: build/intermediates/exploded-aar/com.squareup.assertj/assertj-android/1.0.0/classes.jar: No such file or directory

What needs to happen to trigger the prepare task that explodes the aar? Using a compile dependency triggers the prepareComSquareupAssertjAssertjAndroid100Library task, and the classes.jar is exploded as expected.

Possibly related: I have 3 build types: [release, debug, internal] (internal is basically a debuggable build that is signed with release keys and runs proguard). Sometimes when running ./gradlew clean :testDebug, it runs the prepare task and compiles correctly (and other times it does not). However, when running ./gradlew clean :testInternal, it never runs the prepare task, and compile always fails. Even if the classes.jar is already exploded, it does not seem to pick up the jar at all if it did not execute the prepare task.

It seems the confusion stems from the fact that there are two separate "compile test java" tasks: :compileTestDebugJava and :compileDebugTestJava

Running :compileTestDebugJava:

:preDebugTestBuild
:prepareComSquareupAssertjAssertjAndroid100Library
:prepareComSquareupAssertjAssertjAndroidSupportV4100Library
:prepareDebugTestDependencies
:compileTestDebugJava

compared to :compileDebugTestJava:

:preDebugTestBuild
:prepareComSquareupAssertjAssertjAndroid100Library
:prepareComSquareupAssertjAssertjAndroidSupportV4100Library
:prepareDebugTestDependencies
:compileDebugTestAidl
:processDebugTestManifest
:compileDebugTestRenderscript
:generateDebugTestBuildConfig
:generateDebugTestAssets UP-TO-DATE
:mergeDebugTestAssets
:generateDebugTestResValues UP-TO-DATE
:generateDebugTestResources
:mergeDebugTestResources
:processDebugTestResources
:generateDebugTestSources
:compileDebugTestJava

But the same is not true of the internal buildType, so the :prepareInternalTestDependencies task is not created, which means the prepareComSquareupAssertjAssertJAndroid100Library task is not invoked.

Our CI server runs against the "internal" build type, because that's the build that our QA team uses, and it's the build that is closest to our release build. But this issue is causing those tests to fail because the AAR is not properly exploded. Seems like this is probably a robolectric bug?

Indeed, this seems to be a robolectric gradle bug. Could you please open a bug at the robolectric/robolectric-gradle-plugin project and reference me? And could you create a minimalistic project / test case that recreates this issue? (I'm the author of the original robolectric AAR Integration)

Issue robolectric/robolectric-gradle-plugin#122 has been opened for this, with a test project exhibiting the bug at jhansche/robotest-aar@d32f38a

@JakeWharton Your comment for why using aar instead of jar: "Future-proofing. Maybe we want to ship custom lint rules in the future." is not true anymore. .aar dependencies for androidTestCompile is not allowed since 1.1 android gradle plugin. ;-) so actually it was un-future-proofing ;-).

@pboos could you post a reference to where that is stated? I'm a bit curious.

@plackemacher @JakeWharton i guess i remembered wrong. after checking again i see now that it was because i as well added assertj-android as provided. Because the android gradle plugin starting with 1.1 does not allow aar as provided anymore [some discussion about that topic]. That I do because android studio doesn't seem to pick up the androidTestCompile dependencies correctly [bug report]. Guess will have to find another way to get that working. Or any idea? ;-)

@pboos androidTestCompile works for me, and Android Studio picks it up and allows me to use those classes in the test source. I also had to add this, because my robolectric test code is in src/test/java:

sourceSets {
    androidTest.setRoot('src/test')
}

There was, however, a period of time where Android Studio stopped recognizing my test dependencies and source files, so I couldn't edit any of the src/test/java code as a full-on "class" (just as a .java file). I fixed that by simply re-importing my project into Android Studio -- then it started recognizing my test classes and dependencies again.

@jhansche found out what the problem was for me: https://code.google.com/p/android/issues/detail?id=98326#c3 but kind of hard to figure out.