[prev in list] [next in list] [prev in thread] [next in thread] 

List:       lucene-dev
Subject:    RE: Interfaces
From:       "Robert Engels" <rengels () ix ! netcom ! com>
Date:       2005-03-16 21:41:42
Message-ID: LMENLAOACIBLMOIILNNNCENPEMAA.rengels () ix ! netcom ! com
[Download RAW message or body]

I've been pushing for making IndexReader and IndexWriter interfaces for a
long time (and changing lucene core to use them), but there seems a
reluctance to do so (although I am not sure why). The current factory
methods could be easily moved to a IndexReaderWriter factory class. Probably
a top-level interface IndexReaderWriter with methods like isWritable() for
"read only" indices, and methods getReader(), getWriter().

With a decent IDE a single developer could make all of the changes in about
a half a day, but it would need support of the "team", since the patch would
be huge.

Robert Engels


-----Original Message-----
From: Maik Schreiber [mailto:blizzy-keyword-lucene_dev.6564c8@blizzy.de]
Sent: Wednesday, March 16, 2005 3:33 PM
To: java-dev@lucene.apache.org
Subject: Interfaces


Hi,

I know the issue of using interfaces in Lucene has been discussed a few
times before. I'd like to bring that to the table once again, though,
because I think all those discussions were missing an important point: unit
testing.

Without coding to interfaces it gets quite complicated to test for calls
being made to an IndexWriter, for example. Of course it's possible to
subclass IndexWriter and intercept all relevant calls, it still remains
being a PITA.


Consider the following JUnit test method for testing a hypothetical
Foo.foo(IndexWriter, Document) method that does nothing more than
IndexWriter.addDocument(doc):


public void testFoo() throws IOException {
	final List addedDocuments = new ArrayList();

	Directory dir = new RAMDirectory();
	Analyzer analyzer = new StandardAnalyzer();
	IndexWriter writer = new IndexWriter(dir, analyzer, true) {
		public void addDocument(Document doc) throws IOException {
			super.addDocument(doc);
			addedDocuments.add(doc);
		}
	};

	Document doc = new Document();
	new Foo().foo(writer, doc);

	assertEquals(1, addedDocuments.size());
	assertSame(doc, addedDocuments.get(0));
}


As you can see, you have to go at relatively great lengths just to test for
a single method call. You need to create a Directory for the IndexWriter,
and the IndexWriter instance itself. The IndexWriter really adds the
document to the directory. In addition to that, we're taking notes of the
added documents, so we can assert those later on.

This complexity even grows when doing other this: Say you want to test a
call to IndexReader. The problem is that IndexReader.open() needs to have a
valid index lying around. So to set up the environment for that requirement
you first need to create a fake index in a RAMDirectory using an
IndexWriter, then use that index to test IndexReader calls.


Now this is the same test method as above, but this time using EasyMock and
an interface IIndexWriter (which IndexWriter hypothetically implements):


public void testFoo() throws IOException {
	MockControl writerControl =
		MockControl.createControl(IIndexWriter.class);
	IIndexWriter writer = (IIndexWriter) writerControl.getMock();

	Document doc = new Document();

	writer.addDocument(doc);
	writerControl.setVoidCallable();

	writerControl.replay();

	new Foo().foo(writer, doc);

	writerControl.verify();
}


This time, it's all straightforward: No Directory created, no IndexWriter
created, no document added. We just tell the mocked-up IndexWriter what
method calls to expect and what to return (or do nothing, or throw an
exception). Also there's no taking notes of added documents because EasyMock
does that already.


The net benefit is that there are no useless objects created. Those could
even harm the test results in the worst case. Also the test should run
faster now, which can really add up when you have hundreds or thousands of
tests.

--
Maik Schreiber   *   http://www.blizzy.de

GPG public key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x1F11D713
Key fingerprint: CF19 AFCE 6E3D 5443 9599 18B5 5640 1F11 D713

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


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

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic