### Question:
TableOutputStepAnalyzer extends ConnectionExternalResourceStepAnalyzer<TableOutputMeta> { @Override public Set<ComponentDerivationRecord> getChangeRecords( TableOutputMeta meta ) throws MetaverseAnalyzerException { Set<ComponentDerivationRecord> changes = new HashSet<>(); String[] tableFields = meta.specifyFields() ? meta.getFieldDatabase() : new String[]{}; String[] streamFields = meta.specifyFields() ? meta.getFieldStream() : new String[]{}; if ( getInputs() != null ) { Set<String> stepNames = getInputs().getStepNames(); for ( int i = 0; i < tableFields.length; i++ ) { String tableField = tableFields[ i ]; String streamField = streamFields[ i ]; for ( String stepName : stepNames ) { if ( !RESOURCE.equals( stepName ) && !StringUtils.equals( tableField, streamField ) ) { StepField inputField = new StepField( stepName, streamField ); StepField outField = new StepField( RESOURCE, tableField ); ComponentDerivationRecord change = new ComponentDerivationRecord( inputField, outField ); changes.add( change ); } } } } return changes; }  @Override Set<String> getOutputResourceFields( TableOutputMeta meta ); @Override Set<ComponentDerivationRecord> getChangeRecords( TableOutputMeta meta ); @Override IMetaverseNode getConnectionNode(); @Override Set<Class<? extends BaseStepMeta>> getSupportedSteps(); @Override String getResourceInputNodeType(); @Override String getResourceOutputNodeType(); @Override boolean isOutput(); @Override boolean isInput(); static final String TRUNCATE_TABLE; }### Answer:
@Test public void testGetChangeRecords() throws Exception { String[] tableFields = new String[] { "field2", "field3" }; when( meta.getFieldDatabase() ).thenReturn( tableFields ); String[] streamFields = new String[] { "field2", "field3" }; when( meta.getFieldStream() ).thenReturn( streamFields ); StepNodes inputs = new StepNodes(); inputs.addNode( "prevStep", "f1", node ); inputs.addNode( "prevStep", "field2", node ); inputs.addNode( "prevStep", "field3", node ); inputs.addNode( ExternalResourceStepAnalyzer.RESOURCE, "field2", node ); inputs.addNode( ExternalResourceStepAnalyzer.RESOURCE, "field3", node ); doReturn( inputs ).when( analyzer ).getInputs(); Set<ComponentDerivationRecord> changeRecords = analyzer.getChangeRecords( meta ); assertNotNull( changeRecords ); assertEquals( 0, changeRecords.size() ); when( meta.specifyFields() ).thenReturn( true ); changeRecords = analyzer.getChangeRecords( meta ); assertNotNull( changeRecords ); assertEquals( 0, changeRecords.size() ); tableFields = new String[] { "field2-new", "field3" }; when( meta.getFieldDatabase() ).thenReturn( tableFields ); changeRecords = analyzer.getChangeRecords( meta ); assertNotNull( changeRecords ); assertEquals( 1, changeRecords.size() ); ComponentDerivationRecord field2 = changeRecords.stream().filter( record -> record.getOriginalEntityName() .equals( "field2" ) ).findFirst().orElse( null ); assertNotNull( field2 ); assertEquals( field2.getChangedEntityName(), "field2-new" ); tableFields = new String[] { "field2-new", "field3-new" }; when( meta.getFieldDatabase() ).thenReturn( tableFields ); changeRecords = analyzer.getChangeRecords( meta ); assertNotNull( changeRecords ); assertEquals( 2, changeRecords.size() ); field2 = changeRecords.stream().filter( record -> record.getOriginalEntityName().equals( "field2" ) ) .findFirst().orElse( null ); assertNotNull( field2 ); assertEquals( field2.getChangedEntityName(), "field2-new" ); ComponentDerivationRecord field3 = changeRecords.stream().filter( record -> record.getOriginalEntityName() .equals( "field3" ) ).findFirst().orElse( null ); assertNotNull( field3 ); assertEquals( field3.getChangedEntityName(), "field3-new" ); when( meta.specifyFields() ).thenReturn( false ); changeRecords = analyzer.getChangeRecords( meta ); assertNotNull( changeRecords ); assertEquals( 0, changeRecords.size() ); }