// <著作権>
// Copyright (c) 2008, NTT DATA Corporation.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Text;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using TERASOLUNA.Fw.Common;
using TERASOLUNA.Fw.Common.Configuration.BLogic;
using TERASOLUNA.Fw.CommonUT;
using TERASOLUNA.Fw.CommonUT.Configuration;
using TERASOLUNA.Fw.Common.BLogic;
using TERASOLUNA.Fw.Utlib.Logging;
using TERASOLUNA.Fw.Common.Logging;
using System.Text.RegularExpressions;

namespace TERASOLUNA.Fw.CommonUT.BLogic
{
    ///<summary>
    /// BLogicFactory のテストクラスです。
    ///</summary>
    [TestClass()]
    public class BLogicFactoryTest
    {
        ///<summary>
        /// 正常なblogicNameを表す文字列です。
        ///</summary>
        private readonly string BLOGIC_NAME = "blogic";

        ///<summary>
        /// 不正なblogicNameを表す文字列です。
        ///</summary>
        private readonly string ILLEGAL_BLOGIC_NAME = "illegalBlogic";

        ///<summary>
        /// 正常なジェネリクスの引数を表す文字列です。
        ///</summary>
        private readonly string GENERICS01 = "TERASOLUNA.Fw.CommonUT.BLogic.BLogicFactory_Stub01,TERASOLUNA.Fw.CommonUT";

        ///<summary>
        /// 正常なジェネリクスの引数を表す文字列です。
        ///</summary>
        private readonly string GENERICS02 = "TERASOLUNA.Fw.CommonUT.BLogic.BLogicFactory_Stub02,TERASOLUNA.Fw.CommonUT";

        ///<summary>
        /// 正常なジェネリクスの引数を表す文字列です。
        ///</summary>
        private readonly string GENERICS03 = "TERASOLUNA.Fw.CommonUT.BLogic.BLogicFactory_Stub03,TERASOLUNA.Fw.CommonUT";

        ///<summary>
        /// BLogicFactoryを継承するクラスを表す文字列です。
        ///</summary>
        private readonly string FACTORY_TYPE = "TERASOLUNA.Fw.CommonUT.BLogic.BLogicFactory_BLogicFactoryStub01,TERASOLUNA.Fw.CommonUT";

        ///<summary>
        /// BLogicFactoryを継承しないクラスを表す文字列です。
        ///</summary>
        private readonly string NOT_FACTORY_TYPE = "TERASOLUNA.Fw.CommonUT.BLogic.BLogicFactory_Stub01,TERASOLUNA.Fw.CommonUT";

        ///<summary>
        /// テストデータ01を表す文字列です。
        ///</summary>
        private readonly string CONFIG_FILE_NAME_01 = "BLogicFactory_BLogicConfigSection01.config";

        ///<summary>
        /// テストデータ02を表す文字列です。
        ///</summary>
        private readonly string CONFIG_FILE_NAME_02 = "BLogicFactory_BLogicConfigSection02.config";

        ///<summary>
        /// テストデータ03を表す文字列です。
        ///</summary>
        private readonly string CONFIG_FILE_NAME_03 = "BLogicFactory_BLogicConfigSection03.config";

        ///<summary>
        /// テストデータ04を表す文字列です。
        ///</summary>
        private readonly string CONFIG_FILE_NAME_04 = "BLogicFactory_BLogicConfigSection04.config";

        private TestContext testContextInstance;

        ///<summary>
        /// 現在のテストの実行についての情報および機能を
        /// 提供するテスト コンテキストを取得または設定します。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        #region 追加のテスト属性
        // 
        //テストを作成するときに、次の追加属性を使用することができます:
        //
        //クラスの最初のテストを実行する前にコードを実行するには、ClassInitialize を使用
        //
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //クラスのすべてのテストを実行した後にコードを実行するには、ClassCleanup を使用
        //
        [ClassCleanup()]
        public static void MyClassCleanup()
        {
            ConfigurationManager.AppSettings[TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor.BLOGIC_FACTORY_TYPENAME] = null;
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory = null;
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor.BLOGIC_CONFIGURATION_SECTION_NAME = "blogicConfiguration";
        }
        //
        //各テストを実行する前にコードを実行するには、TestInitialize を使用
        //
        [TestInitialize()]
        public void MyTestInitialize()
        {
            ConfigurationManager.AppSettings[TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor.BLOGIC_FACTORY_TYPENAME] = null;
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory = null;
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor.BLOGIC_CONFIGURATION_SECTION_NAME = "blogicConfiguration";
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = null;
            
            LogUTUtil.Clear();
        }
        //
        //各テストを実行した後にコードを実行するには、TestCleanup を使用
        //
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        #endregion


        ///<summary>
        /// BLogicFactory () のテスト
        ///</summary>
        ///<remarks>
        /// 引数無しのコンストラクタを呼び出した場合、インスタンスが返却されることを確認するテスト。
        ///</remarks>
        [TestMethod()]
        public void ConstructorTest01()
        {
            // 実行
            BLogicFactory target = new BLogicFactory();

            // 検証
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor =
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(target);
            Assert.IsNotNull(accessor.BLogicTypes);
            Assert.AreEqual(0, accessor.BLogicTypes.Count);
            Assert.IsNull(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName が null、genericTypeNames の要素数が 0の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        public void CreateBLogicTest01()
        {
            // 準備
            string blogicName = null;
            string[] genericTypeNames = new string[0];

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(NopBLogic));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory));
            
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor =
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(0, accessor.BLogicTypes.Count);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName が空文字列、genericTypeNames の要素数が 0の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        public void CreateBLogicTest02()
        {
            // 準備
            string blogicName = string.Empty;
            string[] genericTypeNames = new string[0];

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(NopBLogic));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory));

            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor =
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(0, accessor.BLogicTypes.Count);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName がジェネリック型でないクラスを指定する文字列、
        /// genericTypeNames の要素数が 0 の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest03()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];
            
            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(BLogicFactory_IBLogicImpl01));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory));
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor = new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(1, accessor.BLogicTypes.Count);
            Assert.AreEqual(typeof(BLogicFactory_IBLogicImpl01), accessor.BLogicTypes[blogicName]);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName がジェネリック型でないクラスを指定する文字列、
        /// genericTypeNames が null の場合、
        /// ArgumentNullException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest04()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            
            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            try
            {
                // 第2引数に直接 null を指定することで、genericTypeNames = null となる。
                BLogicFactory.CreateBLogic(blogicName, null);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ArgumentNullException e)
            {
                // 成功
                Assert.AreEqual("genericTypeNames", e.ParamName);
            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(1, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
            Assert.IsTrue(LogUTUtil.CheckErrorUseMessageId(
                typeof(BLogicFactory), typeof(ArgumentNullException), "E_NULL_ARGUMENT", "genericTypeNames"));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName が型パラメータを1つ宣言するジェネリック型のクラスを指定する文字列、
        /// genericTypeNames の要素数が 0 の場合、
        /// TerasolunaException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection02.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal02.config")]
        public void CreateBLogicTest05()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];
            
            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_02);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            try
            {
                BLogicFactory.CreateBLogic(blogicName, genericTypeNames);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (TerasolunaException e)
            {
                // 成功
                string exceptionMessage = MessageManager.GetMessage("E_LESS_PARAMS",
                    typeof(BLogicFactory_IBLogicImpl02<>).AssemblyQualifiedName, 1);
                Assert.AreEqual(exceptionMessage, e.Message);
            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName が型パラメータを1つ宣言するジェネリック型のクラスを指定する文字列、
        /// genericTypeNames の要素数が 1 の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection02.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal02.config")]
        public void CreateBLogicTest06()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = { GENERICS01 };
            
            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_02);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(BLogicFactory_IBLogicImpl02<BLogicFactory_Stub01>));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory));
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor = 
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(1, accessor.BLogicTypes.Count);
            Assert.AreEqual(typeof(BLogicFactory_IBLogicImpl02<>), accessor.BLogicTypes[blogicName]);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName が型パラメータを1つ宣言するジェネリック型のクラスを指定する文字列、
        /// genericTypeNames の要素数が 3 の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection02.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal02.config")]
        public void CreateBLogicTest07()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = { GENERICS01, GENERICS02, GENERICS03 };
            
            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_02);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(BLogicFactory_IBLogicImpl02<BLogicFactory_Stub01>));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory));
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor = 
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(1, accessor.BLogicTypes.Count);
            Assert.AreEqual(typeof(BLogicFactory_IBLogicImpl02<>), accessor.BLogicTypes[blogicName]);     

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName がジェネリック型でないクラスを指定する文字列、
        /// genericTypeNames の要素数が 0 、
        /// フィールドの _factory が not null の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest08()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];
            
            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            // _factory のキャッシュ
            BLogicFactory factory = new BLogicFactory();
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory = factory;

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(BLogicFactory_IBLogicImpl01));
            Assert.AreSame(factory, TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor = new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(1, accessor.BLogicTypes.Count);
            Assert.AreEqual(typeof(BLogicFactory_IBLogicImpl01), accessor.BLogicTypes[blogicName]);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 引数の blogicName がジェネリック型でないクラスを指定する文字列、
        /// genericTypeNames の要素数が 0 、
        /// フィールドの _factory が not null、
        /// _blogicTypes のキーに blogicName と同じ文字列が存在する場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest09()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];

            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            // _factory のキャッシュ
            BLogicFactory factory = new BLogicFactory();
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory = factory;

            // _blogicTypes のキャッシュ
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor =
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(factory);
            Type type = typeof(BLogicFactory_IBLogicImpl01);
            accessor.BLogicTypes[blogicName] = type;

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(BLogicFactory_IBLogicImpl01));
            Assert.AreSame(factory, TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(1, accessor.BLogicTypes.Count);
            Assert.AreSame(type, accessor.BLogicTypes[blogicName]);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 構成ファイルに設定する BLogicFactoryTypeName が BLogicFactory 派生クラスの
        /// のインスタンスを生成できない設定の場合、
        /// TerasolunaException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest10()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];

            ConfigurationManager.AppSettings[TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor.BLOGIC_FACTORY_TYPENAME] = NOT_FACTORY_TYPE;

            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            try
            {
                BLogicFactory.CreateBLogic(blogicName, genericTypeNames);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (TerasolunaException e)
            {
                // 成功
                string exceptionMessage = MessageManager.GetMessage("E_INVALID_CAST_TYPE_FROM_GENERICPARAM",
                    typeof(BLogicFactory_Stub01).AssemblyQualifiedName,
                    typeof(BLogicFactory).AssemblyQualifiedName);
                Assert.AreEqual(exceptionMessage, e.Message);

            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 構成ファイルに設定する BLogicFactoryTypeName が BLogicFactory 派生クラスの
        /// のインスタンスを生成できる設定の場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest11()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];

            ConfigurationManager.AppSettings[TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor.BLOGIC_FACTORY_TYPENAME] = FACTORY_TYPE;

            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            // 実行
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName, genericTypeNames);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(BLogicFactory_IBLogicImpl01));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory_BLogicFactoryStub01));
            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor = 
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(1, accessor.BLogicTypes.Count);
            Assert.AreEqual(typeof(BLogicFactory_IBLogicImpl01), accessor.BLogicTypes[blogicName]);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// ビジネスロジック設定ファイルを読み込むことができない場合、
        /// ConfigurationErrorsException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        public void CreateBLogicTest12()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor.BLOGIC_CONFIGURATION_SECTION_NAME = "noBlogicConfiguration";

            try
            {
                BLogicFactory.CreateBLogic(blogicName, genericTypeNames);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (ConfigurationErrorsException e)
            {
                // 成功
                string formatMessage = "アプリケーション構成ファイルの \"blogicConfiguration\" 設定情報が不正です。ファイル \"{0}\\NoTestItem_BLogicExternal01.config\" の読み込みに失敗しました。";
                Assert.AreEqual(string.Format(formatMessage, Environment.CurrentDirectory), e.Message);
            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// ビジネスロジック設定ファイルに設定する blogic 要素の name 属性に、
        /// blogicName と同じキーが存在しない場合、
        /// TerasolunaException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection01.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal01.config")]
        public void CreateBLogicTest13()
        {
            // 準備
            string blogicName = ILLEGAL_BLOGIC_NAME;
            string[] genericTypeNames = new string[0];

            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_01);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            try
            {
                BLogicFactory.CreateBLogic(blogicName, genericTypeNames);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (TerasolunaException e)
            {
                // 成功
                string exceptionMessage = MessageManager.GetMessage("E_BLOGIC_TYPE_NOT_FOUND", ILLEGAL_BLOGIC_NAME);
                Assert.AreEqual(exceptionMessage, e.Message);
            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(1, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
            Assert.IsTrue(LogUTUtil.CheckErrorUseMessageId(
                typeof(BLogicFactory), typeof(TerasolunaException), "E_BLOGIC_TYPE_NOT_FOUND", ILLEGAL_BLOGIC_NAME));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// ビジネスロジック設定ファイルに設定する blogic 要素の name 属性に、
        /// blogicName と同じキーが存在するが、取得したタイプ名から型を解決できない場合、
        /// TerasolunaException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection03.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal03.config")]
        public void CreateBLogicTest14()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];

            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_03);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            try
            {
                BLogicFactory.CreateBLogic(blogicName, genericTypeNames);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (TerasolunaException e)
            {
                // 成功
                string exceptionMessage = MessageManager.GetMessage("E_TYPE_LOAD_FAILED", "IllegalType");
                Assert.AreEqual(exceptionMessage, e.Message);
            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(1, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
            Assert.IsTrue(LogUTUtil.CheckErrorUseMessageId(
                typeof(BLogicFactory), typeof(TerasolunaException), "E_TYPE_LOAD_FAILED", "IllegalType"));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// ビジネスロジック設定ファイルに設定する blogic 要素の name 属性に、
        /// blogicName と同じキーが存在するが、取得したタイプ名から型を解決できるが、
        /// IBLogic 実装クラスのインスタンスを生成できない場合、
        /// TerasolunaException がスローされることを確認するテスト。
        /// </remarks>
        [TestMethod()]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicConfigSection04.config")]
        [DeploymentItem(@"BLogic\BLogicFactoryTestData\BLogicFactory_BLogicExternal04.config")]
        public void CreateBLogicTest15()
        {
            // 準備
            string blogicName = BLOGIC_NAME;
            string[] genericTypeNames = new string[0];

            BLogicConfigurationSection configSection = ConfigTestHelper.GetBLogicConfigurationSectionFromCustomFile(CONFIG_FILE_NAME_04);
            configSection.CreateBLogicElements();
            TERASOLUNA_Fw_Common_Configuration_TerasolunaConfigurationAccessor._blogicConfigSection = configSection;

            try
            {
                BLogicFactory.CreateBLogic(blogicName, genericTypeNames);
                Assert.Fail("到達してはいけないコードです。");
            }
            catch (TerasolunaException e)
            {
                // 成功
                string exceptionMessage = MessageManager.GetMessage("E_MEMBER_ACCESS_EXCEPTION",
                    typeof(BLogicFactory_IBLogicImpl03).AssemblyQualifiedName);
                Assert.AreEqual(exceptionMessage, e.Message);

            }
            catch (Exception e)
            {
                Assert.Fail("到達してはいけないコードです。" + e.ToString());
            }

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }

        /// <summary>
        /// CreateBLogic (string, string[]) のテスト
        /// </summary>
        /// <remarks>
        /// 第一引数の blogicName が null、第二引数に何も値を渡さない場合、
        /// 正常に実行することを確認するテスト。
        /// </remarks>
        [TestMethod()]
        public void CreateBLogicTest16()
        {
            // 準備
            string blogicName = null;

            // 実行
            // 第二引数の可変長引数に何も値を渡さない
            IBLogic actual = BLogicFactory.CreateBLogic(blogicName);

            // 検証
            Assert.IsInstanceOfType(actual, typeof(NopBLogic));
            Assert.IsInstanceOfType(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory, typeof(BLogicFactory));

            TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor accessor =
                new TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor(TERASOLUNA_Fw_Common_BLogic_BLogicFactoryAccessor._factory);
            Assert.AreEqual(0, accessor.BLogicTypes.Count);

            // ログの確認
            Assert.AreEqual(0, LogUTUtil.CountLogs(typeof(BLogicFactory), LogLevel.INFO));
        }
    }

    /// <summary>
    /// IBLogic を実装するスタブです。
    /// デフォルトコンストラクタが存在します。
    /// ジェネリクスの型パラメータ数が 0 です。
    /// </summary>
    public class BLogicFactory_IBLogicImpl01 : IBLogic
    {
        public BLogicFactory_IBLogicImpl01()
        {
        }

        public BLogicResult Execute(BLogicParam param)
        {
            return null;
        }
    }

    /// <summary>
    /// IBLogic を実装するスタブです。。
    /// デフォルトコンストラクタが存在します。
    /// ジェネリクスのパラメータ数が 1 です。
    /// </summary>
    public class BLogicFactory_IBLogicImpl02<T> : IBLogic
    {
        public BLogicFactory_IBLogicImpl02()
        {
        }

        public BLogicResult Execute(BLogicParam param)
        {
            return null;
        }
    }

    /// <summary>
    /// IBLogic を実装しないスタブです。。
    /// デフォルトコンストラクタが存在しません。
    /// ジェネリクスのパラメータ数が 0 です。
    /// </summary>
    public class BLogicFactory_IBLogicImpl03 : IBLogic
    {
        public BLogicFactory_IBLogicImpl03(string str)
        {
        }

        public BLogicResult Execute(BLogicParam param)
        {
            return null;
        }
    }

    /// <summary>
    /// BLogicFactory を継承しないスタブです。
    /// デフォルトコンストラクタが存在します。
    /// ジェネリクスのパラメータ数が0です。
    /// </summary>
    public class BLogicFactory_Stub01
    {
        public BLogicFactory_Stub01()
        {
        }
    }

    /// <summary>
    /// ジェネリクスのパラメータのために使用するクラスです。
    /// </summary>
    public class BLogicFactory_Stub02
    {
    }

    /// <summary>
    /// ジェネリクスのパラメータのために使用するクラスです。
    /// </summary>
    public class BLogicFactory_Stub03
    {
    }

    ///<summary>
    /// BLogicFactoryを継承するスタブです。
    /// デフォルトコンストラクタが存在します。
    ///</summary>
    public class BLogicFactory_BLogicFactoryStub01 : BLogicFactory
    {
        public BLogicFactory_BLogicFactoryStub01()
        {
        }
    }
}
