// 3 InsertQuote
 public static void InsertQuoteIntoDatabaseLogger(
     Action<Quote> insertQuoteIntoDatabase,Action<string> log, Quote quote)
 {
     log($"Start InsertQuoteIntoDatabase with input {quote.Title} {quote.Body}");
     insertQuoteIntoDatabase(quote);
     log($"End InsertQuoteIntoDatabase");
 }
 private static void InsertQuoteIntoDatabase(Quote quote)
 {
     string connectionString =
         @"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Dev\Refactoring\Refactoring\Database1.mdf;Integrated Security=True";
     using (var connection = new SqlConnection(connectionString))
     {
         var cmd = new SqlCommand("INSERT INTO Quotes (Title, Text) VALUES (@Title, @Quote)");
         cmd.Connection = connection;
         cmd.Parameters.AddWithValue("@Title", quote.Title);
         cmd.Parameters.AddWithValue("@Quote", quote.Body);
         connection.Open();
         cmd.ExecuteNonQuery();
     }
 }
        public void QuoteImporter_GivenMockFile_ShouldInsertIntoMockDatabase()
        {
            // 1. ReadFileListOfLines mock
            string actualLineFromFile = "";
            Func<IEnumerable<string>> readFileListOfLines = () =>
            {
                var listOfLines = new[] {"title, quote here"};
                actualLineFromFile = listOfLines[0];
                return listOfLines;
            };

            // 2. ParseLine mock
            string actualLineSentToParseLine = "";
            Func<string, Quote> parseLine = s =>
            {
                actualLineSentToParseLine = s;
                var quote = new Quote {Title = "title2", Body = "quote here2"};
                return quote;
            };

            // 3. InsertQuoteIntoDatabase mock
            // using a closure
            IList<Quote> actualQuotes = new List<Quote>();
            Action<Quote> insertQuoteIntoDatabase = quote =>
            {
                actualQuotes.Add(quote);
            };

            // compose.  Action is a delegate - doesn't return anything
            Action run = () => ImporterFunctional.QuoteImporter(
                readFileListOfLines, parseLine, insertQuoteIntoDatabase);
            run();

            // 1. Testing the ReadFileListOfLines mock was called
            Assert.Equal("title, quote here", actualLineFromFile);

            // 2. Testing the mock parser received the data from the ReadFileListOfLines mock
            Assert.Equal("title, quote here", actualLineSentToParseLine);

            // 3. Testing the mock database received the data from the ParseLine mock
            Assert.Equal("title2", actualQuotes[0].Title);
            Assert.Equal("quote here2", actualQuotes[0].Body);
        }