/** * Copyright 2012 Michael R. Lange <michael.r.lange@langmi.de>. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.langmi.spring.batch.examples.complex.aggregating.writer; import de.langmi.spring.batch.examples.complex.aggregating.AggregatedItem; import de.langmi.spring.batch.examples.complex.support.SimpleItem; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.Test; import org.springframework.batch.core.StepExecution; import static org.junit.Assert.*; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.test.MetaDataInstanceFactory; /** * Test for AggregatingItemsWriter. * * @author Michael R. Lange <michael.r.lange@langmi.de> */ public class AggregatingSimpleItemsWriterTest { private AggregateSimpleItemsWriter writer; private TestItemWriter delegate; private StepExecution stepExecution; /** * Simple test for the standard usecase. * Some write sequences and an exhausted reader at the end. * * I tried to use mock with Mockito, but i can't use it properly * because the items in use are not the same after delegation. * * @throws Exception */ @Test public void testWriteInOrderedSequences() throws Exception { int count = 5; // first write sequence, no item should be written out int valueFirstSequence = 1; int sharedIdFirstSequence = 1000; List<SimpleItem> testData1 = createTestData(count, sharedIdFirstSequence, valueFirstSequence); writer.write(testData1); // check delegate, should have no data yet assertTrue(delegate.getData().isEmpty()); // second write sequence with another shared id int valueSecondSequence = 2; int sharedIdSecondSequence = 2000; List<SimpleItem> testData2 = createTestData(count, sharedIdSecondSequence, valueSecondSequence); writer.write(testData2); // check delegate, should have one entry from sequence before assertEquals(1, delegate.getData().size()); // check shared id assertEquals(sharedIdFirstSequence, delegate.getData().get(0).getId()); // check sum assertEquals(valueFirstSequence * count, delegate.getData().get(0).getSum()); // clear test delegate delegate.resetData(); // third write sequence with yet another shared id int valueThirdSequence = 3; int sharedIdThirdSequence = 3000; List<SimpleItem> testData3 = createTestData(count, sharedIdThirdSequence, valueThirdSequence); writer.write(testData3); // check delegate, should have one entry from sequence before assertEquals(1, delegate.getData().size()); // check shared id assertEquals(sharedIdSecondSequence, delegate.getData().get(0).getId()); // check sum assertEquals(valueSecondSequence * count, delegate.getData().get(0).getSum()); // clear test delegate delegate.resetData(); // set reader exhausted for the fourth sequence stepExecution.getExecutionContext().put("readerExhausted", Boolean.TRUE); int valueFourthSequence = 4; int sharedIdFourthSequence = 4000; List<SimpleItem> testData4 = createTestData(count, sharedIdFourthSequence, valueFourthSequence); writer.write(testData4); // check delegate, should have one entry from sequence before and the last one assertEquals(2, delegate.getData().size()); // check shared id assertEquals(sharedIdThirdSequence, delegate.getData().get(0).getId()); assertEquals(sharedIdFourthSequence, delegate.getData().get(1).getId()); // check sum assertEquals(valueThirdSequence * count, delegate.getData().get(0).getSum()); assertEquals(valueFourthSequence * count, delegate.getData().get(1).getSum()); } /** * Simple test for the standard usecase. * Some write sequences and an exhausted reader at the end. * * I tried to use mock with Mockito, but i can't use it properly * because the items in use are not the same after delegation. * * @throws Exception */ @Test public void testWriteWithChangeInsideSequence() throws Exception { int count = 5; // create a combined set of data with different shared id int valueFirstSequence = 1; int sharedIdFirstSequence = 1000; List<SimpleItem> testData1 = createTestData(count, sharedIdFirstSequence, valueFirstSequence); int valueSecondSequence = 2; int sharedIdSecondSequence = 2000; List<SimpleItem> testData2 = createTestData(count, sharedIdSecondSequence, valueSecondSequence); testData1.addAll(testData2); writer.write(testData1); // check delegate, should have one entry from sequence before assertEquals(1, delegate.getData().size()); // check shared id assertEquals(sharedIdFirstSequence, delegate.getData().get(0).getId()); // check sum assertEquals(valueFirstSequence * count, delegate.getData().get(0).getSum()); } /** * Testdata util method. * * @param count * @param sharedId * @param value * @return */ private List<SimpleItem> createTestData(int count, int sharedId, int value) { List<SimpleItem> testData = new ArrayList<SimpleItem>(); for (int i = 0; i < count; i++) { testData.add(new SimpleItem(i, sharedId, value)); } return testData; } /** * Test Initialization, prepares the writer under test. * @throws Exception */ @Before public void before() throws Exception { writer = new AggregateSimpleItemsWriter(); // delegate delegate = new TestItemWriter(); writer.setDelegate(delegate); // dummy stepExecutionContext stepExecution = MetaDataInstanceFactory.createStepExecution(); writer.beforeStep(stepExecution); } /** * The ItemWriter for use as delegate and for easy checking of values. */ private class TestItemWriter implements ItemWriter<AggregatedItem> { private List<AggregatedItem> data = new ArrayList<AggregatedItem>(); @Override public void write(List<? extends AggregatedItem> items) throws Exception { for (AggregatedItem item : items) { data.add(item); } } public void resetData() { data.clear(); } public List<AggregatedItem> getData() { return data; } } }