jeudi 9 juillet 2015

How do I unit test C# console app and moc database call

I am a new newbie to unit testing. Please help me out.
Scenario: I need to write unit test for C# console app. The entry point (static void main) method takes 3 arguments and call Run() method of another class. In Run method it basically makes a first call to database to get the status of sql server agent jobs and if it is idle then we make a second call to the database to run that sql server agent job.
Example:

internal class Program   
    {    
        static DIContainer container;

        private ILog _log;

        public Program(ILog log)
        {
            _log = log;
        }

        static void Main(string[] args)
        {
            try
            {
                //some code here to get MyProcess
                //var process = blah blah

                try
                {
                    Environment.ExitCode = Myprocess.Run();

                    process.CleanUp();
                }
                catch (Exception e)
                {
                    Environment.ExitCode = -1;
                    program._log.Error(e);
                }


            }
            catch (Exception e2)
            {
                Environment.ExitCode = -2;
                Console.Error.WriteLine(e2);
            }
        }

    }



   internal class MyProcess : IProcess<MyOptions>
    {
        private ILog _log;
        private IConfig _config;

        public MyProcess(ILog log, IConfig config)
        {
            _log = log;
            _config = config;
        }


        public void CleanUp()
        {
            _log.Info("some clean up...");
            _config = null;
            _log = null;
        }

        public int Run()
        {

            SqlParameter jobReturnValue;
            string strJobStatus = string.Empty;
            int jobResult;
            strJobStatus = GetSQLAgentJobStatus();

            if (strJobStatus == "Idle")
            {
                using (SqlConnection conn = new SqlConnection(_config.MyConnectionString))
                {
                    using (SqlCommand ExecJob = new SqlCommand())
                    {
                        ExecJob.Connection = conn;
                        ExecJob.CommandText = "msdb.dbo.sp_start_job";
                        ExecJob.CommandType = CommandType.StoredProcedure;


                        ExecJob.Parameters.AddWithValue("@job_name", "SqlServer_Job_Name_That_Needs_To_Be_Run");

                        jobReturnValue = new SqlParameter("@RETURN_VALUE", SqlDbType.Int);
                        jobReturnValue.Direction = ParameterDirection.ReturnValue;
                        ExecJob.Parameters.Add(jobReturnValue);

                        conn.Open();
                        ExecJob.ExecuteNonQuery();
                        jobResult = (Int32)ExecJob.Parameters["@RETURN_VALUE"].Value;


                        return jobResult;

                    }
                }
            }
            else
            {
                 return 0;                
            }

        }

        private Dictionary<int, string> ExecutionStatusDictionary = new Dictionary<int, string>()
        {
            {0, "Not idle or suspended"},
            {1, "Executing"},
            {2, "Waiting for thread"},
            {3, "Between retries"},
            {4, "Idle"},
            {5, "Suspended"},
            {7, "Performing completion actions"}
        };

        public string GetSQLAgentJobStatus()
        {
            SqlConnection msdbConn = new SqlConnection(_config.MyConnectionString);
            string strStatus = string.Empty;

            try
            {
                msdbConn.Open();

                SqlCommand jobStatusCommand = msdbConn.CreateCommand();

                jobStatusCommand.CommandType = CommandType.StoredProcedure;
                jobStatusCommand.CommandText = "msdb.dbo.sp_help_job";

                SqlParameter jobName = jobStatusCommand.Parameters.Add("@job_name", SqlDbType.VarChar);
                jobName.Direction = ParameterDirection.Input;
                jobName.Value = "SqlServerAgent_Job_Name";


                SqlParameter jobAspect = jobStatusCommand.Parameters.Add("@job_aspect", SqlDbType.VarChar);
                jobAspect.Direction = ParameterDirection.Input;
                jobAspect.Value = "JOB";//job information

                SqlDataReader jobStatusReader = jobStatusCommand.ExecuteReader();

                while (jobStatusReader.Read())
                {
                    strStatus = ExecutionStatusDictionary[(int)jobStatusReader["current_execution_status"]];
                }

                jobStatusReader.Close();
            }
            finally
            {
                msdbConn.Close();
            }

            return strStatus;            
        }

    }

So my questions are
1)how do I unit test input to the console app and static void main Method
2)How do I mock database call using moq framework

Aucun commentaire:

Enregistrer un commentaire