diff --git a/vnftools/provider/pom.xml b/vnftools/provider/pom.xml
index 05ec84a..2fbeac8 100644
--- a/vnftools/provider/pom.xml
+++ b/vnftools/provider/pom.xml
@@ -22,6 +22,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.onap.ccsdk.sli.core</groupId>
             <artifactId>sli-common</artifactId>
             <version>${sdnctl.sli.version}</version>
diff --git a/vnftools/provider/src/main/java/org/onap/sdnc/vnftools/VnfTools.java b/vnftools/provider/src/main/java/org/onap/sdnc/vnftools/VnfTools.java
index 08ed435..a452a4a 100644
--- a/vnftools/provider/src/main/java/org/onap/sdnc/vnftools/VnfTools.java
+++ b/vnftools/provider/src/main/java/org/onap/sdnc/vnftools/VnfTools.java
@@ -3,7 +3,7 @@
  * openECOMP : SDN-C
  * ================================================================================
  * Copyright (C) 2017 AT&T Intellectual Property. All rights
- * 							reserved.
+ *                             reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,15 +21,6 @@
 
 package org.onap.sdnc.vnftools;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
@@ -37,175 +28,153 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.Properties;
+
 public class VnfTools implements SvcLogicJavaPlugin {
-	// ========== FIELDS ==========
+    static final String BASE = "base";
+    static final String FILENAME = "filename";
+    static final String RESULT_CTX_STRING = "result_ctx_string";
+    static final String RETURN_KEY = "return-key";
+    static final String RETURN_PATH = "return-path";
+    static final String STRING_TO_FIND = "string_to_find";
+    static final String STRING_TO_SEARCH = "string_to_search";
+    static final String SUFFIX = "suffix";
+    static final String TRUE_STRING = "true";
 
-	private static final Logger LOG = LoggerFactory.getLogger(VnfTools.class);
+    private static final Logger LOG = LoggerFactory.getLogger(VnfTools.class);
 
-	// ========== CONSTRUCTORS ==========
+    public VnfTools(Properties props) {
+        if (props != null) {
+            LOG.debug("props is not null.");
+        }
+    }
 
-	public VnfTools(Properties props) {
-		if (props != null) {
-			LOG.debug("props is not null.");
-		}
-	}
+    public void checkIfActivateReady(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        LOG.debug("Checking if enough data is available to send the NCS Activate request...");
+
+        SliPluginUtils.checkParameters(parameters, new String[]{RETURN_KEY}, LOG);
+        setIfNotNull(parameters.get(RETURN_KEY), TRUE_STRING, ctx);
+    }
+
+    /**
+     * DG node performs a java String.contains(String) and writes true or false
+     * to a key in context memory.
+     * @param parameters HashMap in context memory must contain the following:
+     * <table border='1'>
+     * <thead>
+     *     <th>Key</th>
+     *     <th>Description</th>
+     * </thead>
+     * <tbody>
+     *     <tr>
+     *         <td>string_to_search</td>
+     *         <td>String to perform java String.contains(String) on</td>
+     *     </tr>
+     *  <tr>
+     *         <td>string_to_find</td>
+     *         <td>String to find in the string_to_search</td>
+     *     </tr>
+     *  <tr>
+     *         <td>result_ctx_string</td>
+     *         <td>Context memory key to write the result ("true" or "false") to</td>
+     *     </tr>
+     * </tbody>
+     * </table>
+     * @param ctx Reference to context memory
+     * @throws SvcLogicException when passed in parameter is not valid
+     */
+    public void stringContains(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        SliPluginUtils.checkParameters(
+                parameters, new String[]{STRING_TO_SEARCH, STRING_TO_FIND, RESULT_CTX_STRING}, LOG);
+        setIfNotNull(parameters.get(RESULT_CTX_STRING),
+                Boolean.toString(parameters.get(STRING_TO_SEARCH).contains(parameters.get(STRING_TO_FIND))),
+                ctx);
+    }
 
 
-	public void checkIfActivateReady( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
-		LOG.debug("Checking if enough data is available to send the NCS Activate request...");
+    public void generateName(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        LOG.debug("generateName");
 
-		SliPluginUtils.checkParameters(parameters, new String[]{"return-key"}, LOG);
-		final String returnKey = parameters.get("return-key");
-		ctx.setAttribute(returnKey, "true");
+        SliPluginUtils.checkParameters(parameters, new String[]{BASE, SUFFIX, RETURN_PATH}, LOG);
 
-	}
+        String base = parameters.get(BASE);
+        int baseLength = base.length();
+        if (baseLength < 4) {
+            String errorMessage = String.format("Parameter(%s) needs at least length 4 but only have %d",
+                    BASE, baseLength);
+            LOG.error(errorMessage);
+            throw new SvcLogicException(errorMessage);
+        }
 
-	/**
-	 * DG node performs a java String.contains(String) and writes true or false
-	 * to a key in context memory.
-	 * @param parameters Hashmap in context memory must contain the following:
-	 * <table border='1'>
-	 * <thead>
-	 * 	<th>Key</th>
-	 * 	<th>Description</th>
-	 * </thead>
-	 * <tbody>
-	 * 	<tr>
-	 * 		<td>string_to_search</td>
-	 * 		<td>String to perform java String.contains(String) on</td>
-	 * 	</tr>
-	 *  <tr>
-	 * 		<td>string_to_find</td>
-	 * 		<td>String to find in the string_to_search</td>
-	 * 	</tr>
-	 *  <tr>
-	 * 		<td>result_ctx_string</td>
-	 * 		<td>Context memory key to write the result ("true" or "false") to</td>
-	 * 	</tr>
-	 * </tbody>
-	 * </table>
-	 * @param ctx Reference to context memory
-	 * @throws SvcLogicException
-	 */
-	public void stringContains( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
-		SliPluginUtils.checkParameters(parameters, new String[]{"string_to_search","string_to_find","result_ctx_string"}, LOG);
-		ctx.setAttribute(parameters.get("result_ctx_string"), Boolean.toString(parameters.get("string_to_search").contains(parameters.get("string_to_find"))));
-	}
+        setIfNotNull(parameters.get(RETURN_PATH), String.format("%s%s%s",
+                base.substring(0, baseLength - 4), parameters.get(SUFFIX), base.substring(baseLength - 2)),
+                ctx);
+    }
 
+    private void setIfNotNull(String property, String value, SvcLogicContext ctx) {
+        if (property != null && value != null) {
+            LOG.debug("Setting ", property, " to ",  value);
+            ctx.setAttribute(property, value);
+        }
+    }
 
-	public void generateName( Map<String, String> parameters, SvcLogicContext ctx ) throws SvcLogicException {
-		LOG.debug("generateName");
+    public void printContext(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
+        if (parameters == null) {
+            throw new SvcLogicException("no parameters passed");
+        }
 
-		SliPluginUtils.checkParameters(parameters, new String[]{"base","suffix","return-path"}, LOG);
+        String fileName = parameters.get(FILENAME);
 
-		String base = parameters.get("base");
-		ctx.setAttribute( parameters.get("return-path"), base.substring(0, base.length() - 4) + parameters.get("suffix") + base.substring(base.length() - 2) );
-	}
+        if ((fileName == null) || (fileName.length() == 0)) {
+            throw new SvcLogicException("printContext requires 'filename' parameter");
+        }
 
+        PrintStream pstr = null;
 
-	private boolean matches(String str1, String str2) {
-		if (str1 == null) {
-			if (str2 == null) {
-				return true;
-			} else {
-				return false;
-			}
-		} else {
-			if (str2 == null) {
-				return false;
-			} else {
-				return str1.equals(str2);
-			}
-		}
-	}
+        try (FileOutputStream fileStream = new FileOutputStream(new File(fileName), true)){
+            pstr = new PrintStream(fileStream);
+        } catch (IOException e1) {
+            LOG.error("FileOutputStream close exception: ", e1);
+        }
+        catch (Exception e) {
+            throw new SvcLogicException("Cannot open file " + fileName, e);
+        } finally {
+            if (pstr != null) {
+                pstr.println("#######################################");
+                for (String attr : ctx.getAttributeKeySet()) {
+                    pstr.println(attr + " = " + ctx.getAttribute(attr));
+                }
 
-	private void setIfNotNull(String property, String value, SvcLogicContext ctx) {
-		if (value != null) {
-			LOG.debug("Setting " + property + " to " + value);
-			ctx.setAttribute(property, value);
-		}
-	}
+                pstr.flush();
+                pstr.close();
+            }
+        }
 
-	/*
-	 * Moves an array element from one index to another
-	 */
-	private void copyArrayEntry(String srcRoot, String destRoot, SvcLogicContext ctx) {
-		LOG.debug("copyArrayEntry called: srcRoot=" + srcRoot + ", destRoot=" + destRoot);
+    }
 
-		// Record all of the source keys
-		List<String> keysToMove = new ArrayList<String>();
-		for (String key : ctx.getAttributeKeySet()) {
-			if (key.startsWith(srcRoot)) {
-				keysToMove.add(key);
-			}
-		}
+    static int getArrayLength(SvcLogicContext ctx, String key) {
+        String value = ctx.getAttribute(key);
+        try {
+            return Integer.parseInt(value);
+        } catch( NumberFormatException e ) {
+            LOG.debug(String.format("Ctx contained key(%s) value(%s) is not integer", key, value));
+        }
 
-		// Now loop through and copy those keys to the destination, and then delete the source
-		for (String key : keysToMove) {
-			String suffix = key.substring(srcRoot.length());
-			LOG.debug("Move " + key + " to " + destRoot + suffix);
-			ctx.setAttribute(destRoot + suffix, ctx.getAttribute(key));
-			ctx.setAttribute(key, null);
-		}
+        return 0;
+    }
 
-	}
+    static int getArrayLength(SvcLogicContext ctx, String key, String debug) {
+        try {
+            return Integer.parseInt(ctx.getAttribute(key));
+        } catch( NumberFormatException e ) {
+            LOG.debug(debug);
+        }
 
-	public void printContext(Map<String, String> parameters, SvcLogicContext ctx) throws SvcLogicException {
-		if (parameters == null) {
-			throw new SvcLogicException("no parameters passed");
-		}
-
-		String fileName = parameters.get("filename");
-
-		if ((fileName == null) || (fileName.length() == 0)) {
-			throw new SvcLogicException("printContext requires 'filename' parameter");
-		}
-
-		PrintStream pstr = null;
-
-		try (FileOutputStream fileStream = new FileOutputStream(new File(fileName), true)){
-			pstr = new PrintStream(fileStream);
-		} catch (IOException e1) {
-			LOG.error("FileOutputStream close exception: ", e1);
-		}
-		catch (Exception e) {
-			throw new SvcLogicException("Cannot open file " + fileName, e);
-		}
-
-		pstr.println("#######################################");
-		for (String attr : ctx.getAttributeKeySet()) {
-			pstr.println(attr + " = " + ctx.getAttribute(attr));
-		}
-
-		pstr.flush();
-		pstr.close();
-	}
-
-	static int getArrayLength( SvcLogicContext ctx, String key ) {
-		try {
-			return Integer.parseInt(ctx.getAttribute(key));
-		} catch( NumberFormatException e ) {}
-
-		return 0;
-	}
-
-	static int getArrayLength( SvcLogicContext ctx, String key, String debug ) {
-		try {
-			return Integer.parseInt(ctx.getAttribute(key));
-		} catch( NumberFormatException e ) {
-			LOG.debug(debug);
-		}
-
-		return 0;
-	}
-
-	/**
-	 * Returns true if string is null or empty.
-	 * @param str
-	 * @return
-	 */
-	private static boolean stringIsBlank( String str ) {
-		return str == null || str.isEmpty();
-	}
-
+        return 0;
+    }
 }
diff --git a/vnftools/provider/src/test/java/org/onap/sdnc/vnftools/VnfToolsTest.java b/vnftools/provider/src/test/java/org/onap/sdnc/vnftools/VnfToolsTest.java
new file mode 100644
index 0000000..b30ff86
--- /dev/null
+++ b/vnftools/provider/src/test/java/org/onap/sdnc/vnftools/VnfToolsTest.java
@@ -0,0 +1,212 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : SDN-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.sdnc.vnftools;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+
+public class VnfToolsTest {
+    private SvcLogicContext mockSvcLogicContext = mock(SvcLogicContext.class);
+
+    private VnfTools vnfTools;
+
+    @Before
+    public void setUp() throws Exception {
+        vnfTools = new VnfTools(null);
+    }
+
+    @Test
+    public void testConstructor() throws Exception {
+        VnfTools vTools = new VnfTools(null);
+        Assert.assertTrue("Should have no impact with null property", vTools != null);
+        vTools = new VnfTools(new Properties());
+        Assert.assertTrue("Should have created", vTools != null);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void testCheckIfActivateReadyFailure() throws Exception {
+        vnfTools.checkIfActivateReady(null, mockSvcLogicContext);
+    }
+
+    @Test
+    public void testCheckIfActivateReady() throws Exception {
+        String value = "testing";
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put(VnfTools.RETURN_KEY, value);
+        vnfTools.checkIfActivateReady(parameters, mockSvcLogicContext);
+        Mockito.verify(mockSvcLogicContext, times(1)).setAttribute(value, VnfTools.TRUE_STRING);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void testStringContainsFailure() throws Exception {
+        vnfTools.stringContains(null, mockSvcLogicContext);
+    }
+
+    @Test
+    public void testStringContains() throws Exception {
+        String value = "result ctx string";
+        String stringToFindValue = "testing";
+        String stringToSearchValue = "testing 1234";
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put(VnfTools.RESULT_CTX_STRING, value);
+        parameters.put(VnfTools.STRING_TO_FIND, stringToFindValue);
+        parameters.put(VnfTools.STRING_TO_SEARCH, stringToSearchValue);
+
+        vnfTools.stringContains(parameters, mockSvcLogicContext);
+        Mockito.verify(mockSvcLogicContext, times(1)).setAttribute(
+                value, Boolean.toString(stringToSearchValue.contains(stringToFindValue)));
+
+        stringToFindValue = "1234";
+        vnfTools.stringContains(parameters, mockSvcLogicContext);
+        Mockito.verify(mockSvcLogicContext, times(2)).setAttribute(
+                value, Boolean.toString(stringToSearchValue.contains(stringToFindValue)));
+    }
+
+    @Test
+    public void testGenerateNameFailure() throws Exception {
+        try {
+            vnfTools.generateName(null, mockSvcLogicContext);
+            Assert.fail("should have throw SvcLogicException");
+        } catch (SvcLogicException e) {
+            Assert.assertFalse("Should be validation error",
+                    e.getMessage().contains("needs at least length 4 but only have"));
+        }
+    }
+
+    @Test
+    public void testGenerateNameFailWithShortBaseParam() throws Exception {
+        String value = "return path";
+        String base = "123";
+        String suffix = "suffix";
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put(VnfTools.RETURN_PATH, value);
+        parameters.put(VnfTools.BASE, base);
+        parameters.put(VnfTools.SUFFIX, suffix);
+
+        try {
+            vnfTools.generateName(parameters, mockSvcLogicContext);
+            Assert.fail("should have throw SvcLogicException");
+        } catch (SvcLogicException e) {
+            Assert.assertTrue("Should be length error",
+                    e.getMessage().contains("needs at least length 4 but only have"));
+        }
+    }
+
+    @Test
+    public void testGenerateName() throws Exception {
+        String value = "return path";
+        String base = "1234567890";
+        String suffix = "suffix";
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put(VnfTools.RETURN_PATH, value);
+        parameters.put(VnfTools.BASE, base);
+        parameters.put(VnfTools.SUFFIX, suffix);
+
+        vnfTools.generateName(parameters, mockSvcLogicContext);
+        String expectedValue = String.format("%s%s%s",
+                base.substring(0, base.length() - 4), suffix, base.substring(base.length() - 2));
+        Mockito.verify(mockSvcLogicContext, times(1)).setAttribute(value, expectedValue);
+    }
+
+    @Test
+    public void testPrintContextInParamNullFailure() throws Exception {
+        try {
+            vnfTools.printContext(null, mockSvcLogicContext);
+            Assert.fail("should have throw SvcLogicException");
+        } catch(SvcLogicException e) {
+            Assert.assertEquals("Should be no param error", "no parameters passed", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPrintContextFileNameFailure() throws Exception {
+        String expectedEmessage = "printContext requires 'filename' parameter";
+        Map<String, String> parameters = new HashMap<>();
+        try {
+            vnfTools.printContext(parameters, mockSvcLogicContext);
+            Assert.fail("should have throw SvcLogicException");
+        } catch(SvcLogicException e) {
+            Assert.assertEquals("Should be missing filename error", expectedEmessage, e.getMessage());
+        }
+
+        parameters.put(VnfTools.FILENAME, "");
+        try {
+            vnfTools.printContext(parameters, mockSvcLogicContext);
+            Assert.fail("should have throw SvcLogicException");
+        } catch(SvcLogicException e) {
+            Assert.assertEquals("Should still be missing filename error", expectedEmessage, e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPrintContext() throws Exception {
+        Map<String, String> parameters = new HashMap<>();
+        parameters.put(VnfTools.FILENAME, "abc");
+        vnfTools.printContext(parameters, mockSvcLogicContext);
+    }
+
+    @Test
+    public void testGetArrayLengthInvalidInt() throws Exception {
+        String key = "abc";
+        Mockito.doReturn("efg").when(mockSvcLogicContext).getAttribute(key);
+        int result = VnfTools.getArrayLength(mockSvcLogicContext, key);
+        Assert.assertEquals("Should return 0 for string value", 0, result);
+    }
+
+    @Test
+    public void testGetArrayLength() throws Exception {
+        String key = "abc";
+        String value = "234";
+        Mockito.doReturn(value).when(mockSvcLogicContext).getAttribute(key);
+        int result = VnfTools.getArrayLength(mockSvcLogicContext, key);
+        Assert.assertEquals("Should return the value int", Integer.parseInt(value), result);
+    }
+
+    @Test
+    public void testGetArrayLengthWithDebugInvalidInt() throws Exception {
+        String key = "abc";
+        Mockito.doReturn("efg").when(mockSvcLogicContext).getAttribute(key);
+        int result = VnfTools.getArrayLength(mockSvcLogicContext, key, "debug");
+        Assert.assertEquals("Should return 0 for string value", 0, result);
+    }
+
+    @Test
+    public void testGetArrayLengthWithDebug() throws Exception {
+        String key = "abc";
+        String value = "234";
+        Mockito.doReturn(value).when(mockSvcLogicContext).getAttribute(key);
+        int result = VnfTools.getArrayLength(mockSvcLogicContext, key, "debug");
+        Assert.assertEquals("Should return the value int", Integer.parseInt(value), result);
+    }
+
+}
\ No newline at end of file
