diff --git a/bin/dunitrust-server/Cargo.toml b/bin/dunitrust-server/Cargo.toml
index 082f968b9958684334eab76ad8e512e8dc8cd94d..e2fac712fbbd52ca9cb2117a91433d126da18ae5 100644
--- a/bin/dunitrust-server/Cargo.toml
+++ b/bin/dunitrust-server/Cargo.toml
@@ -20,7 +20,7 @@ durs-ws2p = { path = "../../lib/modules/ws2p/ws2p" }
 durs-ws2p-v1-legacy = { path = "../../lib/modules/ws2p-v1-legacy" }
 #human-panic = "1.0.1"
 log = "0.4.8"
-structopt= "0.3.4"
+structopt = "0.3.4"
 
 [target.'cfg(unix)'.dependencies]
 durs-tui = { path = "../../lib/modules/tui" }
diff --git a/lib/core/conf/Cargo.toml b/lib/core/conf/Cargo.toml
index bb34ff368f00dd16a68bf6671209c089d7a0fb2f..3c510c8492031ee275c57498c3bfe1e0d8225cd8 100644
--- a/lib/core/conf/Cargo.toml
+++ b/lib/core/conf/Cargo.toml
@@ -27,6 +27,7 @@ serde_json = "1.0.*"
 unwrap = "1.2.1"
 
 [dev-dependencies]
+durs-module = { path = "../module", features = ["module-test"] }
 maplit = "1.0.2"
 once_cell = "1.3.1"
 
diff --git a/lib/core/conf/src/modules_conf.rs b/lib/core/conf/src/modules_conf.rs
index ab54a2816cfae66c04899213f1e9edd7eea03c7b..21a323f3a57d1455164078f9832c24b8a64108d6 100644
--- a/lib/core/conf/src/modules_conf.rs
+++ b/lib/core/conf/src/modules_conf.rs
@@ -54,9 +54,7 @@ impl ModulesConf {
     ) -> Result<(M::ModuleConf, Option<M::ModuleUserConf>), ModuleConfError> {
         let file_module_user_conf: M::ModuleUserConf =
             if let Some(module_conf_json) = module_conf_json {
-                let file_module_user_conf_opt: Option<M::ModuleUserConf> =
-                    serde_json::from_str(module_conf_json.to_string().as_str())?;
-                file_module_user_conf_opt.unwrap_or_default()
+                serde_json::from_str(module_conf_json.to_string().as_str())?
             } else {
                 M::ModuleUserConf::default()
             };
@@ -66,7 +64,7 @@ impl ModulesConf {
         M::generate_module_conf(
             currency_name,
             global_conf,
-            Some(file_module_user_conf.merge(env_module_user_conf)),
+            Some(env_module_user_conf.merge(file_module_user_conf)),
         )
     }
 
@@ -117,18 +115,17 @@ pub fn get_module_conf_and_keys<M: DursModule<DuRsConf, DursMsg>>(
 mod tests {
 
     use super::*;
+    use crate::global_conf::v2::DuRsGlobalConfV2;
+    use crate::global_conf::DuRsGlobalConf;
+    use dup_crypto::keys::{ed25519, KeyPairEnum};
+    use durs_module::module_test::*;
     use once_cell::sync::Lazy;
+    use serde_json::json;
     use std::sync::Mutex;
 
     // Empty mutex used to ensure that only one test runs at a time
     static MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
 
-    #[derive(Debug, Default, Deserialize, PartialEq)]
-    struct TestModuleUserConf {
-        field1: Option<String>,
-        field2: Option<usize>,
-    }
-
     #[inline]
     fn prefix() -> String {
         format!("{}MODULE_TEST_", constants::DURS_ENV_PREFIX)
@@ -143,13 +140,117 @@ mod tests {
         }
     }
 
+    fn keypairs() -> DuniterKeyPairs {
+        DuniterKeyPairs {
+            network_keypair: KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair::generate_random()),
+            member_keypair: None,
+        }
+    }
+
+    #[test]
+    fn test_get_empty_module_conf() -> Result<(), ModuleConfError> {
+        let _lock = MUTEX.lock().expect("MUTEX poisoned");
+        clear_env_vars();
+
+        let (confs, keys): ModuleConfsAndKeys<ModuleTest<DuRsConf, DursMsg>> =
+            get_module_conf_and_keys::<ModuleTest<DuRsConf, DursMsg>>(
+                None,
+                &DuRsGlobalConf::V2(DuRsGlobalConfV2::default()),
+                None,
+                keypairs(),
+            )?;
+
+        assert_eq!(
+            (
+                ModuleTestConf::default(),
+                Some(ModuleTestUserConf::default())
+            ),
+            confs,
+        );
+        assert_eq!(RequiredKeysContent::None, keys,);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_get_module_conf_from_file() -> Result<(), ModuleConfError> {
+        let _lock = MUTEX.lock().expect("MUTEX poisoned");
+        clear_env_vars();
+
+        let json_conf = json!({
+            "field1": "toto",
+            "field2": 123,
+        });
+
+        let (confs, _): ModuleConfsAndKeys<ModuleTest<DuRsConf, DursMsg>> =
+            get_module_conf_and_keys::<ModuleTest<DuRsConf, DursMsg>>(
+                None,
+                &DuRsGlobalConf::V2(DuRsGlobalConfV2::default()),
+                Some(json_conf),
+                keypairs(),
+            )?;
+
+        assert_eq!(
+            (
+                ModuleTestConf {
+                    field1: "toto".to_owned(),
+                    field2: 123,
+                },
+                Some(ModuleTestUserConf {
+                    field1: Some("toto".to_owned()),
+                    field2: Some(123),
+                })
+            ),
+            confs,
+        );
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_get_module_conf_from_env_and_file() -> Result<(), ModuleConfError> {
+        let _lock = MUTEX.lock().expect("MUTEX poisoned");
+        clear_env_vars();
+
+        std::env::set_var(&format!("{}FIELD2", prefix()), "456");
+
+        let json_conf = json!({
+            "field1": "toto",
+            "field2": 123,
+        });
+
+        let (confs, _): ModuleConfsAndKeys<ModuleTest<DuRsConf, DursMsg>> =
+            get_module_conf_and_keys::<ModuleTest<DuRsConf, DursMsg>>(
+                None,
+                &DuRsGlobalConf::V2(DuRsGlobalConfV2::default()),
+                Some(json_conf),
+                keypairs(),
+            )?;
+
+        assert_eq!(
+            (
+                ModuleTestConf {
+                    field1: "toto".to_owned(),
+                    field2: 456,
+                },
+                Some(ModuleTestUserConf {
+                    field1: Some("toto".to_owned()),
+                    field2: Some(456),
+                })
+            ),
+            confs,
+        );
+
+        Ok(())
+    }
+
     #[test]
     fn test_env_module_conf_without_env_vars() -> Result<(), ModuleConfError> {
         let _lock = MUTEX.lock().expect("MUTEX poisoned");
         clear_env_vars();
 
         assert_eq!(
-            TestModuleUserConf::default(),
+            ModuleTestUserConf::default(),
             ModulesConf::get_env_module_user_conf(ModuleStaticName("module_test"))?,
         );
 
@@ -165,7 +266,7 @@ mod tests {
         std::env::set_var(&format!("{}FIELD2", prefix()), "4");
 
         assert_eq!(
-            TestModuleUserConf {
+            ModuleTestUserConf {
                 field1: Some("toto".to_owned()),
                 field2: Some(4),
             },
@@ -184,7 +285,7 @@ mod tests {
         std::env::set_var(&format!("{}FIELD2", prefix()), "toto");
 
         if let Err(ModuleConfError::EnvyErr(_)) = ModulesConf::get_env_module_user_conf::<
-            TestModuleUserConf,
+            ModuleTestUserConf,
         >(ModuleStaticName("module_test"))
         {
             Ok(())
diff --git a/lib/core/module/src/lib.rs b/lib/core/module/src/lib.rs
index 24178da4dc148208359931a7a55f4ad0203d2f42..e65d654d425e7d2300a3a0a656f51599a54baaca 100644
--- a/lib/core/module/src/lib.rs
+++ b/lib/core/module/src/lib.rs
@@ -18,7 +18,6 @@
 
 #![deny(
     clippy::option_unwrap_used,
-    clippy::result_unwrap_used,
     missing_docs,
     missing_debug_implementations,
     missing_copy_implementations,
diff --git a/lib/core/module/src/module_test.rs b/lib/core/module/src/module_test.rs
index 12ad14da05f1385c0f62013b085fc4ce12888563..7da5a1a340be630f3046208019c35fe383a42bb1 100644
--- a/lib/core/module/src/module_test.rs
+++ b/lib/core/module/src/module_test.rs
@@ -46,8 +46,10 @@ impl Merge for ModuleTestUserConf {
 /// Module test config
 #[derive(Clone, Debug, Default, Deserialize, PartialEq)]
 pub struct ModuleTestConf {
-    field1: String,
-    field2: usize,
+    /// Field 1
+    pub field1: String,
+    /// Field 2
+    pub field2: usize,
 }
 
 #[derive(StructOpt, Debug, Clone)]
@@ -79,12 +81,18 @@ impl<DC: DursConfTrait, M: ModuleMessage> DursModule<DC, M> for ModuleTest<DC, M
     fn generate_module_conf(
         _currency_name: Option<&CurrencyName>,
         _global_conf: &<DC as DursConfTrait>::GlobalConf,
-        _module_user_conf: Option<Self::ModuleUserConf>,
+        module_user_conf_opt: Option<Self::ModuleUserConf>,
     ) -> Result<(Self::ModuleConf, Option<Self::ModuleUserConf>), ModuleConfError> {
-        Ok((
-            ModuleTestConf::default(),
-            Some(ModuleTestUserConf::default()),
-        ))
+        let module_conf = if let Some(module_user_conf) = module_user_conf_opt.clone() {
+            ModuleTestConf {
+                field1: module_user_conf.field1.unwrap_or_default(),
+                field2: module_user_conf.field2.unwrap_or_default(),
+            }
+        } else {
+            ModuleTestConf::default()
+        };
+
+        Ok((module_conf, module_user_conf_opt))
     }
     fn exec_subcommand(
         _soft_meta_datas: &SoftwareMetaDatas<DC>,