square / sqlbrite

A lightweight wrapper around SQLiteOpenHelper which introduces reactive stream semantics to SQL operations.
https://square.github.io/sqlbrite/3.x/sqlbrite/
Apache License 2.0
4.57k stars 416 forks source link

Support for unit testing surrounding code is missing or undocumented #228

Closed randallmitchell closed 6 years ago

randallmitchell commented 6 years ago

BriteDatabase is final and therefore cannot be mocked. For me, this means code that using SqlBrite's database functionality cannot be unit tested by graceful means. Is there any existing mechanism or intention for this library to support unit testing?

If there is an existing mechanism to support unit testing, it maybe needs documentation and I'd be happy to contribute that documentation.

In the interim, putting a light wrapper around the database may be a viable workaround. I'm working on proofing that out in sample code and can report my findings here... though QueryObservable is also final... potentially compounding the problem or making the potential workaround non-viable.

JakeWharton commented 6 years ago

There is no need to mock BriteDatabase. If you're testing queries and mapping you can use an in-memory DB by supplying null as the filename. If you want to fake the mapped values (e.g., List<Foo>) then you should have a higher-level of abstraction like a "store" or "repository" that you can mock/fake which knows nothing about SQL.

BriteDatabase operates at a level of abstraction that is unsuitable for mocking, as your tests would become tied to the consuming code. Every change in how you query would require a change in how you mock which is a strong indicator that you're mocking something not meant to be mocked.

randallmitchell commented 6 years ago

I missed the open helper feature for in-memory databases. Thanks you.

I'm actually working on writing tests for my repository. I typically prefer to pass in a mocked persistence layer to my repositories. I will evaluate this pattern against your point about tying tests to query implementation. It has cause some pain. Thanks again.

artem-zinnatullin commented 6 years ago

Another option could be Robolectric, which will provide JVM-compatible implementation of SQLiteOpenHelper with actual SQLite under the hood.

But, of course Robolectric is very questionable answer to "unit" testing.

// And of course it's possible to mock SQLiteOpenHelper and delegate calls to manually JNI-linked SQLite if you don't want to use Robolectric.

On Fri, Dec 15, 2017 at 2:37 PM Randall Mitchell notifications@github.com wrote:

I missed the open helper feature for in-memory databases. Thanks you.

I'm actually working on writing tests for my repository. I typically prefer to pass in a mocked persistence layer to my repositories. I will evaluate this pattern against your point about tying tests to query implementation. It has cause some pain. Thanks again.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/square/sqlbrite/issues/228#issuecomment-351984962, or mute the thread https://github.com/notifications/unsubscribe-auth/AA7B3PyBY79tnVZgWAqDGcFz2PLaJpFOks5tAln-gaJpZM4RCLbO .

JakeWharton commented 6 years ago

I have a hard time recommending Robolectric for anything serious as the Sqlite it uses is built for the JVM and lacks the ICU support that Android provides. This means if you're using anything like collation you'll get different results. That being said, it's always better than mocking. You should never mock queries against the DB. Your tests won't actually be tests, they'll just be scripts to appease your implementation.

On Fri, Dec 15, 2017 at 2:44 PM Artem Zinnatullin :slowpoke: < notifications@github.com> wrote:

Another option could be Robolectric, which will provide JVM-compatible implementation of SQLiteOpenHelper with actual SQLite under the hood.

But, of course Robolectric is very questionable answer to "unit" testing.

// And of course it's possible to mock SQLiteOpenHelper and delegate calls to manually JNI-linked SQLite if you don't want to use Robolectric.

On Fri, Dec 15, 2017 at 2:37 PM Randall Mitchell <notifications@github.com

wrote:

I missed the open helper feature for in-memory databases. Thanks you.

I'm actually working on writing tests for my repository. I typically prefer to pass in a mocked persistence layer to my repositories. I will evaluate this pattern against your point about tying tests to query implementation. It has cause some pain. Thanks again.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/square/sqlbrite/issues/228#issuecomment-351984962, or mute the thread < https://github.com/notifications/unsubscribe-auth/AA7B3PyBY79tnVZgWAqDGcFz2PLaJpFOks5tAln-gaJpZM4RCLbO

.

— You are receiving this because you modified the open/close state.

Reply to this email directly, view it on GitHub https://github.com/square/sqlbrite/issues/228#issuecomment-352094755, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEESoYKIKulF7jYHXEsmTv97kgIn5gks5tAswUgaJpZM4RCLbO .