diff --git a/lib/ansible/modules/storage/netapp/na_ontap_ucadapter.py b/lib/ansible/modules/storage/netapp/na_ontap_ucadapter.py
index bf3a31f7e40..a8c4598b272 100644
--- a/lib/ansible/modules/storage/netapp/na_ontap_ucadapter.py
+++ b/lib/ansible/modules/storage/netapp/na_ontap_ucadapter.py
@@ -76,6 +76,7 @@ import traceback
 from ansible.module_utils.basic import AnsibleModule
 from ansible.module_utils._text import to_native
 import ansible.module_utils.netapp as netapp_utils
+from ansible.module_utils.netapp_module import NetAppModule
 
 HAS_NETAPP_LIB = netapp_utils.has_netapp_lib()
 
@@ -99,14 +100,8 @@ class NetAppOntapadapter(object):
             supports_check_mode=True
         )
 
-        params = self.module.params
-
-        # set up state variables
-        self.state = params['state']
-        self.adapter_name = params['adapter_name']
-        self.node_name = params['node_name']
-        self.mode = params['mode']
-        self.type = params['type']
+        self.na_helper = NetAppModule()
+        self.parameters = self.na_helper.set_parameters(self.module.params)
 
         if HAS_NETAPP_LIB is False:
             self.module.fail_json(msg="the python NetApp-Lib module is required")
@@ -123,96 +118,99 @@ class NetAppOntapadapter(object):
         :rtype: dict
         """
         adapter_info = netapp_utils.zapi.NaElement('ucm-adapter-get')
-        adapter_info.add_new_child('adapter-name', self.adapter_name)
-        adapter_info.add_new_child('node-name', self.node_name)
-        result = self.server.invoke_successfully(adapter_info, True)
-        return_value = None
-        adapter_attributes = result.get_child_by_name('attributes').\
-            get_child_by_name('uc-adapter-info')
-        return_value = {
-            'mode': adapter_attributes.get_child_content('mode'),
-            'pending-mode': adapter_attributes.get_child_content('pending-mode'),
-            'type': adapter_attributes.get_child_content('fc4-type'),
-            'pending-type': adapter_attributes.get_child_content('pending-fc4-type'),
-            'status': adapter_attributes.get_child_content('status'),
-        }
-        return return_value
+        adapter_info.add_new_child('adapter-name', self.parameters['adapter_name'])
+        adapter_info.add_new_child('node-name', self.parameters['node_name'])
+        try:
+            result = self.server.invoke_successfully(adapter_info, True)
+        except netapp_utils.zapi.NaApiError as error:
+            self.module.fail_json(msg='Error fetching ucadapter details: %s: %s'
+                                      % (self.parameters['node_name'], to_native(error)),
+                                  exception=traceback.format_exc())
+        if result.get_child_by_name('attributes'):
+            adapter_attributes = result.get_child_by_name('attributes').\
+                get_child_by_name('uc-adapter-info')
+            return_value = {
+                'mode': adapter_attributes.get_child_content('mode'),
+                'pending-mode': adapter_attributes.get_child_content('pending-mode'),
+                'type': adapter_attributes.get_child_content('fc4-type'),
+                'pending-type': adapter_attributes.get_child_content('pending-fc4-type'),
+                'status': adapter_attributes.get_child_content('status'),
+            }
+            return return_value
+        return None
 
     def modify_adapter(self):
         """
         Modify the adapter.
         """
-        params = {'adapter-name': self.adapter_name,
-                  'node-name': self.node_name}
-        if self.type is not None:
-            params['fc4-type'] = self.type
-        if self.mode is not None:
-            params['mode'] = self.mode
+        params = {'adapter-name': self.parameters['adapter_name'],
+                  'node-name': self.parameters['node_name']}
+        if self.parameters['type'] is not None:
+            params['fc4-type'] = self.parameters['type']
+        if self.parameters['mode'] is not None:
+            params['mode'] = self.parameters['mode']
         adapter_modify = netapp_utils.zapi.NaElement.create_node_with_children(
             'ucm-adapter-modify', ** params)
         try:
             self.server.invoke_successfully(adapter_modify,
                                             enable_tunneling=True)
         except netapp_utils.zapi.NaApiError as e:
-            self.module.fail_json(msg='Error modifying adapter %s: %s' % (self.adapter_name, to_native(e)),
+            self.module.fail_json(msg='Error modifying adapter %s: %s' % (self.parameters['adapter_name'], to_native(e)),
                                   exception=traceback.format_exc())
 
-    def offline_adapter(self):
+    def online_or_offline_adapter(self, status):
         """
-        Bring a Fibre Channel target adapter offline.
+        Bring a Fibre Channel target adapter offline/online.
         """
-        adapter_offline = netapp_utils.zapi.NaElement('fcp-adapter-config-down')
-        adapter_offline.add_new_child('fcp-adapter', self.adapter_name)
-        adapter_offline.add_new_child('node', self.node_name)
+        if status == 'down':
+            adapter = netapp_utils.zapi.NaElement('fcp-adapter-config-down')
+        elif status == 'up':
+            adapter = netapp_utils.zapi.NaElement('fcp-adapter-config-up')
+        adapter.add_new_child('fcp-adapter', self.parameters['adapter_name'])
+        adapter.add_new_child('node', self.parameters['node_name'])
         try:
-            self.server.invoke_successfully(adapter_offline,
+            self.server.invoke_successfully(adapter,
                                             enable_tunneling=True)
         except netapp_utils.zapi.NaApiError as e:
-            self.module.fail_json(msg='Error trying to offline fc-adapter %s: %s' % (self.adapter_name, to_native(e)),
+            self.module.fail_json(msg='Error trying to %s fc-adapter %s: %s' % (status, self.parameters['adapter_name'], to_native(e)),
                                   exception=traceback.format_exc())
 
-    def online_adapter(self):
+    def autosupport_log(self):
         """
-        Bring a Fibre Channel target adapter online.
+        Autosupport log for ucadater
+        :return:
         """
-        adapter_online = netapp_utils.zapi.NaElement('fcp-adapter-config-up')
-        adapter_online.add_new_child('fcp-adapter', self.adapter_name)
-        adapter_online.add_new_child('node', self.node_name)
-        try:
-            self.server.invoke_successfully(adapter_online,
-                                            enable_tunneling=True)
-        except netapp_utils.zapi.NaApiError as e:
-            self.module.fail_json(msg='Error trying to online fc-adapter %s: %s' % (self.adapter_name, to_native(e)),
-                                  exception=traceback.format_exc())
+        results = netapp_utils.get_cserver(self.server)
+        cserver = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=results)
+        netapp_utils.ems_log_event("na_ontap_ucadapter", cserver)
 
     def apply(self):
         ''' calling all adapter features '''
         changed = False
-        results = netapp_utils.get_cserver(self.server)
-        cserver = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=results)
-        netapp_utils.ems_log_event("na_ontap_ucadapter", cserver)
         adapter_detail = self.get_adapter()
 
         def need_to_change(expected, pending, current):
             if expected is None:
                 return False
-            if pending is not None:
+            elif pending is not None:
                 return pending != expected
-            if current is not None:
+            elif current is not None:
                 return current != expected
             return False
 
         if adapter_detail:
-            changed = need_to_change(self.type, adapter_detail['pending-type'], adapter_detail['type']) or \
-                need_to_change(self.mode, adapter_detail['pending-mode'], adapter_detail['mode'])
+            changed = need_to_change(self.parameters.get('type'), adapter_detail['pending-type'],
+                                     adapter_detail['type']) or need_to_change(self.parameters.get('mode'),
+                                                                               adapter_detail['pending-mode'],
+                                                                               adapter_detail['mode'])
 
         if changed:
             if self.module.check_mode:
                 pass
             else:
-                self.offline_adapter()
+                self.online_or_offline_adapter('down')
                 self.modify_adapter()
-                self.online_adapter()
+                self.online_or_offline_adapter('up')
 
         self.module.exit_json(changed=changed)
 
diff --git a/test/units/modules/storage/netapp/test_na_ontap_ucadapter.py b/test/units/modules/storage/netapp/test_na_ontap_ucadapter.py
new file mode 100644
index 00000000000..3a0ca710ec8
--- /dev/null
+++ b/test/units/modules/storage/netapp/test_na_ontap_ucadapter.py
@@ -0,0 +1,159 @@
+# (c) 2018, NetApp, Inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+''' unit tests ONTAP Ansible module: na_ontap_ucadapter '''
+
+from __future__ import print_function
+import json
+import pytest
+
+from units.compat import unittest
+from units.compat.mock import patch, Mock
+from ansible.module_utils import basic
+from ansible.module_utils._text import to_bytes
+import ansible.module_utils.netapp as netapp_utils
+
+from ansible.modules.storage.netapp.na_ontap_ucadapter \
+    import NetAppOntapadapter as my_module  # module under test
+
+if not netapp_utils.has_netapp_lib():
+    pytestmark = pytest.mark.skip('skipping as missing required netapp_lib')
+
+
+def set_module_args(args):
+    """prepare arguments so that they will be picked up during module creation"""
+    args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
+    basic._ANSIBLE_ARGS = to_bytes(args)  # pylint: disable=protected-access
+
+
+class AnsibleExitJson(Exception):
+    """Exception class to be raised by module.exit_json and caught by the test case"""
+    pass
+
+
+class AnsibleFailJson(Exception):
+    """Exception class to be raised by module.fail_json and caught by the test case"""
+    pass
+
+
+def exit_json(*args, **kwargs):  # pylint: disable=unused-argument
+    """function to patch over exit_json; package return data into an exception"""
+    if 'changed' not in kwargs:
+        kwargs['changed'] = False
+    raise AnsibleExitJson(kwargs)
+
+
+def fail_json(*args, **kwargs):  # pylint: disable=unused-argument
+    """function to patch over fail_json; package return data into an exception"""
+    kwargs['failed'] = True
+    raise AnsibleFailJson(kwargs)
+
+
+class MockONTAPConnection(object):
+    ''' mock server connection to ONTAP host '''
+
+    def __init__(self, kind=None, parm1=None):
+        ''' save arguments '''
+        self.type = kind
+        self.parm1 = parm1
+        self.xml_in = None
+        self.xml_out = None
+
+    def invoke_successfully(self, xml, enable_tunneling):  # pylint: disable=unused-argument
+        ''' mock invoke_successfully returning xml data '''
+        self.xml_in = xml
+        if self.type == 'ucadapter':
+            xml = self.build_ucadapter_info(self.parm1)
+        self.xml_out = xml
+        return xml
+
+    def autosupport_log(self):
+        ''' mock autosupport log'''
+        return None
+
+    @staticmethod
+    def build_ucadapter_info(status):
+        ''' build xml data for ucadapter_info '''
+        xml = netapp_utils.zapi.NaElement('xml')
+        data = {'attributes': {'uc-adapter-info': {
+            'mode': 'fc',
+            'pending-mode': 'abc',
+            'type': 'target',
+            'pending-type': 'intitiator',
+            'status': status,
+        }}}
+        xml.translate_struct(data)
+        print(xml.to_string())
+        return xml
+
+
+class TestMyModule(unittest.TestCase):
+    ''' a group of related Unit Tests '''
+
+    def setUp(self):
+        self.mock_module_helper = patch.multiple(basic.AnsibleModule,
+                                                 exit_json=exit_json,
+                                                 fail_json=fail_json)
+        self.mock_module_helper.start()
+        self.addCleanup(self.mock_module_helper.stop)
+        self.server = MockONTAPConnection()
+        self.use_vsim = False
+
+    def set_default_args(self):
+        if self.use_vsim:
+            hostname = '10.192.39.6'
+            username = 'admin'
+            password = 'netapp123'
+            node_name = 'bumblebee-reloaded-01'
+            adapter_name = '0f'
+        else:
+            hostname = 'hostname'
+            username = 'username'
+            password = 'password'
+            node_name = 'abc'
+            adapter_name = '0f'
+        return dict({
+            'hostname': hostname,
+            'username': username,
+            'password': password,
+            'node_name': node_name,
+            'adapter_name': adapter_name,
+        })
+
+    def test_module_fail_when_required_args_missing(self):
+        ''' required arguments are reported as errors '''
+        with pytest.raises(AnsibleFailJson) as exc:
+            set_module_args({})
+            my_module()
+        print('Info: %s' % exc.value.args[0]['msg'])
+
+    def test_ensure_ucadapter_get_called(self):
+        ''' fetching ucadapter details '''
+        set_module_args(self.set_default_args())
+        my_obj = my_module()
+        my_obj.server = self.server
+        get_adapter = my_obj.get_adapter()
+        print('Info: test_ucadapter_get: %s' % repr(get_adapter))
+        assert get_adapter is None
+
+    def test_ensure_apply_for_ucadapter_called(self):
+        ''' configuring ucadaptor and checking idempotency '''
+        module_args = {}
+        module_args.update(self.set_default_args())
+        module_args.update({'type': 'target'})
+        module_args.update({'mode': 'initiator'})
+        set_module_args(module_args)
+        my_obj = my_module()
+        my_obj.autosupport_log = Mock(return_value=None)
+        if not self.use_vsim:
+            my_obj.server = self.server
+        with pytest.raises(AnsibleExitJson) as exc:
+            my_obj.apply()
+        print('Info: test_ucadapter_apply: %s' % repr(exc.value))
+        assert not exc.value.args[0]['changed']
+        if not self.use_vsim:
+            my_obj.server = MockONTAPConnection('ucadapter', 'up')
+        with pytest.raises(AnsibleExitJson) as exc:
+            my_obj.apply()
+        print('Info: test_ucadapter_apply: %s' % repr(exc.value))
+        assert exc.value.args[0]['changed']