hatepoint / phrases-hyperskill-tests

0 stars 1 forks source link

Test should avoid assuming existence of particular classes or methods (Black box testing) #16

Closed RedJocker closed 1 year ago

RedJocker commented 1 year ago

On 4th stage you are making direct references to classes from your solution and their methods (AppDatabase, PhraseDao), we should avoid doing that since user implementation might not have those and lead to build failures.

try rewriting database tests using the TestDatabaseFactory provided on AbstractUnitTest

RedJocker commented 1 year ago

You intend to make a fifth stage right?

I think I can handle rewriting stage4 and you move to stage5, unless stage5 tests depends a lot on stage4 tests

hatepoint commented 1 year ago

No, there's no stage 5. I intended to finish other tasks related to this project (like issues and better descriptions) so if you can help rewriting this it would be nice

RedJocker commented 1 year ago

No, there's no stage 5.

ok.

I intended to finish other tasks related to this project (like issues and better descriptions) so if you can help rewriting this it would be nice

I just wrote a version using TestDatabaseFactory, but I'm having issues. Running each @Test in isolation behaves mostly as expected, but if I run all @test then it does not work. I think the problem is the use of singleton by solution on the Room database code. I know that it is the usual way, but junit does not re-instantiate "static" variables, so I'm getting this error message

Exception, test failed on activity creation with java.lang.IllegalStateException: Illegal connection pointer 68. Current pointers for thread Thread[SDK 29 Main Thread,5,SDK 29] []
java.lang.IllegalStateException: Illegal connection pointer 68. Current pointers for thread Thread[SDK 29 Main Thread,5,SDK 29] []
    at org.robolectric.shadows.ShadowLegacySQLiteConnection$Connections.getConnection(ShadowLegacySQLiteConnection.java:411)
    at org.robolectric.shadows.ShadowLegacySQLiteConnection$Connections.getStatement(ShadowLegacySQLiteConnection.java:420)
    at org.robolectric.shadows.ShadowLegacySQLiteConnection$Connections.executeStatementOperation(ShadowLegacySQLiteConnection.java:833)
    at org.robolectric.shadows.ShadowLegacySQLiteConnection$Connections.resetStatementAndClearBindings(ShadowLegacySQLiteConnection.java:811)
    at org.robolectric.shadows.ShadowLegacySQLiteConnection.nativeResetStatementAndClearBindings(ShadowLegacySQLiteConnection.java:325)
    at android.database.sqlite.SQLiteConnection.nativeResetStatementAndClearBindings(SQLiteConnection.java)
    at android.database.sqlite.SQLiteConnection.releasePreparedStatement(SQLiteConnection.java:1012)
    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:612)
    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
    at android.database.sqlite.SQLiteProgram.__constructor__(SQLiteProgram.java:61)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java)
    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java)
    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1443)
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1418)
    at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.java:161)
    at androidx.room.RoomDatabase.query(RoomDatabase.java:446)
    at androidx.room.util.DBUtil.query(DBUtil.java:83)
    at org.hyperskill.phrases.data.room.PhraseDao_Impl.getAll(PhraseDao_Impl.java:175)
    at org.hyperskill.phrases.data.PhrasesRepository.getAll(PhrasesRepository.kt:33)
    at org.hyperskill.phrases.ui.MainViewModel.<init>(MainViewModel.kt:26)
    at org.hyperskill.phrases.MainViewHolderFactory.create(MainViewHolderFactory.kt:12)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
    at org.hyperskill.phrases.MainActivity.onCreate(MainActivity.kt:31)
    at android.app.Activity.performCreate(Activity.java:7802)
    at android.app.Activity.performCreate(Activity.java:7791)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
    at org.robolectric.android.internal.RoboMonitoringInstrumentation.callActivityOnCreate(RoboMonitoringInstrumentation.java:284)
    at org.robolectric.android.controller.ActivityController.lambda$create$0(ActivityController.java:113)
    at org.robolectric.shadows.ShadowPausedLooper.runPaused(ShadowPausedLooper.java:203)
    at org.robolectric.android.controller.ActivityController.create(ActivityController.java:113)
    at org.robolectric.android.controller.ActivityController.setup(ActivityController.java:286)
    at org.hyperskill.phrases.internals.AbstractUnitTest.testActivity(AbstractUnitTest.kt:80)
    at org.hyperskill.phrases.internals.AbstractUnitTest.testActivity$default(AbstractUnitTest.kt:77)
    at org.hyperskill.phrases.Stage4UnitTest.test01_checkRecyclerViewIsUsingDatabase(Stage4UnitTest.kt:75)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:591)
    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:274)
    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:88)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)

I still don't know how to solve this, but I'll keep looking for a solution.

hatepoint commented 1 year ago

I got that error message as well. Maybe my previous solution where I use @Before and @After might help you solving that?