lucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Erik Hatcher <e...@ehatchersolutions.com>
Subject Re: [subscriptions] Please make org.apache.lucene.index.IndexWriter non-final
Date Sun, 05 Oct 2003 21:10:37 GMT
On Sunday, October 5, 2003, at 04:56  PM, Mike Hogan wrote:
> Setting up an interface as you suggest is what I did, and I create mock
> impls of that as I need in other test cases.  But I also want to unit 
> test
> the  _implementation_ itself?  Here is the full code of the 
> implementation:

Ok, so let's say you can subclass IndexWriter (which you can with the 
current codebase).  How would this change what you have below?

> public class LuceneSearchService implements SearchService {
>     private static final String INDEX_FILE_PATH = "index";

This is something you'd need to change, I'd assume.  Perhaps put in 
some kind of DirectoryFactory - and return a RAMDirectory or 
FSDirectory??

I don't see what a MockIndexWriter would do.

>             writer = new IndexWriter(INDEX_FILE_PATH, new
> StandardAnalyzer(), !indexExists());

Because you'd need to change this somehow.

>     //This is impossible to unit test as Hits is final, and the 
> constructor
> is package protected
>     public int search(final String query, int beginIndex, final int
> endIndex, final List collector) throws SearchService.Exception {


I don't understand your comment here.  Show me how you'd like to phrase 
the test if package permissions would let you.

You aren't passing Hits back out from here, what good would it do to 
mock it?

> You are right that this code as it currently stands cannot be unit 
> tested
> using mock-objects.  Thats because I tried to do so, ran into the final
> problem, then rolled back.  I will show you roughly how the code 
> looked when
> I refactored it to be mock-ready:

Ah, ok, so forget what I said above....

> public class LuceneSearchService implements SearchService {
>     private static final String INDEX_FILE_PATH = "index";
>     private Context context = new DefaultContext();
>
>     public void setContext(Context c) {
>         this.context = c;
>     }
>
> public void index(String componentId, String componentDescription) 
> throws
> SearchService.Exception {
>         IndexWriter writer = null;
>         try {
>             writer = context.createIndexWriter(INDEX_FILE_PATH, new
> StandardAnalyzer(), !indexExists());

Take this a step further, and have a createDirectory instead, that can 
return a RAMDirectory.  Forget about a MockIndexWriter.  Trust me :)

> public static interface Context {
>     IndexWriter createIndexWriter(String path, Analyzer a, boolean 
> create);
> }

Don't lock yourself into a file system index.  Please.  You might want 
it in RAM one day :)  (like in your unit tests)

> I don't know if you see any value in that, but I do.  I cannot do it 
> because
> IndexWriter is final and I cannot create a MockIndexWriter.  I can do a
> RAMDirectory and use the real Lucene API, but I find that less 
> convenient
> than the above.  Do you not agree?

You just aren't seeing the forest from the trees here.  You need to 
refactor and just let IndexWriter be internal and not mocked, but how 
you get at a Directory be flexible for testing.  Even if you always use 
a file system directory even for testing, I highly recommend you bind 
to abstractions not concreteness.  Bind to Directory, not IndexWriter 
as your "interface".

	Erik


---------------------------------------------------------------------
To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: lucene-dev-help@jakarta.apache.org


Mime
View raw message