square / assertj-android

A set of AssertJ helpers geared toward testing Android.
https://square.github.io/assertj-android/
Apache License 2.0
1.58k stars 156 forks source link

Unable to import static method assertThat #129

Closed plackemacher closed 9 years ago

plackemacher commented 10 years ago

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 10 years ago

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

dsvoronin commented 10 years ago

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 10 years ago
    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' 
entropitor commented 10 years ago

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)

Yougin commented 10 years ago

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'

jekopena commented 10 years ago

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

plackemacher commented 10 years ago

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

JakeWharton commented 10 years ago

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

JurgenCruz commented 10 years ago

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

f2prateek commented 10 years ago

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

chrisjenx commented 9 years ago

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

joshskeen commented 9 years ago

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;
ronshapiro commented 9 years ago

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

JakeWharton commented 9 years ago

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 https://github.com/square/assertj-android/issues/129#issuecomment-57497961 .

bgorkowy commented 9 years ago

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.

vpratfr commented 9 years ago

Same issue here. Using Android Studio 0.8.10 and 0.8.11.

lgvalle commented 9 years ago

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

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

emilesvt commented 9 years ago

:+1: 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.

jhansche commented 9 years ago

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")
imminent commented 9 years ago

:+1: to future-proofing.

emartynov commented 9 years ago

Finally it works with latest robolectric plugin!

Skylark95 commented 9 years ago

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.

plackemacher commented 9 years ago

@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.

jhansche commented 9 years ago

@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.

jhansche commented 9 years ago

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?

ChristianKatzmann commented 9 years ago

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)

jhansche commented 9 years ago

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

pboos commented 9 years ago

@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 ;-).

plackemacher commented 9 years ago

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

pboos commented 9 years ago

@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? ;-)

jhansche commented 9 years ago

@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.

pboos commented 9 years ago

@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.