Month: June 2020

  • ขั้นตอนการขอใช้บริการ PSU Groupmail

    กรุณาดำเนินการกรอกเอกสาร ตามขั้นตอนต่อไปนี้ครับ
    Download เอกสาร

    http://group.psu.ac.th/docs/F_SD13.pdf

    วิธีกรอก

    https://sysadmin.psu.ac.th/2017/01/05/acrobat-reader-dc-free-but-sufficient/

    วิธีการใช้งานเบื้องต้น

    http://group.psu.ac.th/docs/MailingList-20090625.pdf


    แล้วส่งกลับมาทาง email ได้เลยครับ  ()

    PSU Groupmail ตั้งต้นจะเป็น @group.psu.ac.th นะครับหากต้องการให้แปลงเป็น @psu.ac.th ช่วยแจ้งด้วย
    ส่วนการส่ง Email ออกไปในนามหน่วยงาน ให้ทำตามนี้

    วิธีส่ง email ออกไปในนามหน่วยงาน ด้วย PSU Webmail
    https://sysadmin.psu.ac.th/2020/03/27/psu-webmail-sent-email-on-behalf-of/

    วิธีส่ง email ในนามหน่วยงาน ที่ออกจาก Gmail ให้เป็น @psu.ac.th หรือ @group.psu.ac.th

    https://sysadmin.psu.ac.th/2018/01/26/send-gmail-in-the-name-of-psu/

  • วิธีสร้าง Running Number ข้อมูลที่ถูก Filter ใน Excel

    หลายครั้งที่เรา ใช้ Excel แล้วใส่ Filter  เพื่อดูกลุ่มข้อมูลที่สนใจ และพบปัญหาว่าลำดับข้อมูลที่เคยเรียงอยู่ ไม่เรียงเหมือนเดิม เช่น  1,3,7,8 แล้วจะทำยังไงดีล่ะ

    ซึ่งใน Excel จะมี Function SUBTOTAL ซึ่งช่วยทำการคำนวณเฉพาะข้อมูลที่ยังคงมองเห็นอยู่หลังถูก Filter ไปแล้วโดย

    รูปแบบคำสั่งของ SUBTOTAL คือ SUBTOTAL (function_num, ref1, [ref2], …)

    โดยจะมี function_code ฟังก์ชันที่จะใช้ในการรวมผลย่อย

    1 คือ AVERAGE

    2 คือ COUNT

    3 คือ COUNTA

    4 คือ MAX

    5 คือ MIN

    6 คือ PRODUCT

    7 คือ STDEV

    8 คือ STDEVP

    9 คือ SUM

    10 คือ VAR

    11 คือ VARP

    ในที่นี้เราใช้ code 3 (COUNTA) ในการนับจำนวนข้อมูลจากแถวแรกถึงแถวที่จะใส่เลขลำดับนั้นๆ เพื่อให้รู้ว่ามีข้อมูลกี่รายการหลังถูก Filter ไปแล้ว

    ตัวอย่างวันนี้
    เป็นข้อมูลจากการสำรวจ size เสื้อขององค์กร เมื่อเรา Filter หน่วยงานที่สังกัด เพื่อที่จะดูว่าใครสั่ง size เสื้ออะไรบ้าง สามารถเขียนสูตรในแถวที่ 2 ได้ ดังนี้ =SUBTOTAL(3,B2:B2) โดยคอลัมน์ที่เราใช้ในสูตร ต้องไม่มีค่าว่าง

    ในตัวอย่างนี้จะใช้ คอลัมน์ B (ชื่อ-สกุล) หรือ C (หน่วยงานที่สังกัด) ก็ได้

    การ copy สูตร ควรจะ fix cell Reference เพื่อไม่ให้สูตรเลื่อน จะได้เป็น

    =SUBTOTAL(3,B$2:B2)

    ซึ่งสูตรนี้จะไม่นับแถวสุดท้ายของการ filter จึงต้อง คูณด้วย *1 เพื่อให้เอาแถวสุดท้ายของการ filter มานับด้วย สุดท้ายจึงผลลัพธ์ของสูตรออกมา

    =SUBTOTAL(3,B$2:B2)*1

    จากนั้นเราสามารถ copy สูตรมาใช้ได้ทั้งคอลัมน์

    เมื่อทำการ filter หลังจากใช้สูตร จากรูปสังเกตในช่องสูตรลำดับที่ 1 เดิมจะเป็นข้อมูล แถวที่ 2 คอลัมน์ที่ 3 นั้นเอง

    ขอขอบคุณ :https://www.inwexcel.com

  • [Adobe XD Tips] How to สร้าง Prototype จาก UI ที่ออกแบบไว้แล้ว

    สวัสดีเพื่อนๆชาว IT/Graphic ทุกท่าน วันนี้เราเคล็ดลับง่ายๆในการสร้าง Prototype ระบบด้วยการนำรูปภาพ User Interface(UI) ที่มีอยู่หรือออกแบบไว้แล้วด้วยเครื่องมือฟรีและดีนั้นคือ Adobe XD

    Prototype คืออะไร

    Prototype คือ การทำ Interactive User Interface หรือหน้าตาของระบบที่สามารถตอบสนองต่อผู้ใช้ โดยไม่ต้องเขียน code เลย เช่น การคลิกปุ่มใดปุ่มหนึ่งในหน้า UI ทำให้มีการเปลี่ยนหน้าหรือเปลี่ยนสถานะของ object ในหน้านั้นๆ

    การทำ Prototype นั้นจะทำให้ Developer สามารถทำงานได้ง่ายขึ้น รู้ Flow การทำงานของระบบ อีกทั้งยังสามารถทำเพื่อใช้ในการนำเสนอระบบงานกับลูกค้าได้โดยไม่ต้อง coding

    ถึงเวลาลงมือทำกัน ลุยยย!!

    ขั้นตอนแรกเราจะต้องเตรียมไฟล์รูป UI ที่ออกแบบไว้แล้วไม่ว่าจะทำด้วย Microsoft Powerpoint, Adobe Photoshop, Adobe Illustrator หรือโปรแกรมอื่นๆ

    ขั้นตอนต่อไป เปิดโปรแกรม Adobe XD ขึ้นมาและสร้างหน้าว่างๆขึ้นมา โดย Adobe XD จะมี template ให้เลือกหลักๆเป็น mobile, tablet และ หน้า website ซึ่งขึ้นอยู่กับผู้ใช้ว่าต้องการสร้าง Prototype สำหรับ Device ประเภทไหนหรืออิงจากขนาดจาก UI ที่ออกแบบไว้เดิมก็สามารถเลือกในส่วนของ Custom Size ได้เช่นกัน

    หลังจากเลือก blank template มาแล้ว ณ ที่นี้ได้เลือก Web 1920 นั้นคือหน้าจอ website ขนาด 1920×1080 ก็จะได้หน้าต่างมาหน้าตาแบบนี้

    เราจะเริ่มจากการทำงานใน Tab แรกกันก่อนนั้นคือ Tab ของ Design เลือกได้จาก Menu Bar ข้างบน

    หลักการของขั้นตอนนี้ คือการนำรูป UI ที่ทำไว้แล้วมาวางลงในตัว Artboard สีขาว 1 หน้า UI จะถูกวางใน Artboard เพียง 1อันและขยายให้เต็ม

    หลังจากนำรูปมาวางแล้ว เราเพิ่มหน้า Artboard ยังไงหละ?? เราจะใช้เครื่องมือที่ชื่อว่า Artboard Tool จากแถบเครื่องมือด้านซ้าย เมื่อคลิกใช้เครื่องมือแล้วตัว Curser ของเราจะเปลี่ยนไปเป็นรูป + เราสามารถคลิกตรงพื้นที่สีเทาเพื่อสร้างหน้าใหม่ขึ้นมาได้เลย (แค่คลิกนะ ไม่ต้องลาก เพราะถ้าลากจะเป็นการสร้างแบบกำหนดขนาดเอง)

    สร้างไปให้จำนวนหน้าว่างเท่ากับจำนวนไฟล์ภาพ UI ที่เรามนำภาพ UI มาวางจนครบ

    ขั้นตอนต่อไปสำคัญมากๆ นั้นคือ การสร้างการเชื่อมโยงระหว่าง Artboard ของเรา โดยปกติแล้วถ้าเราเริ่มออกแบบระบบด้วย Adobe XD ตั้งแต่เริ่ม เราสามารถเลือกได้ว่าวัตถุชิ้นไหนในหน้านี้ที่สามารถคลิกแล้วมีผลอะไรตามมาบ้างได้เลย แต่เราออกแบบมาแล้ว ได้วัตถุมาแค่ชิ้นเดียวนั้นก็คือรูป

    ” เราจะทำการสร้างสี่เหลี่ยมล่องหนขึ้นมาแทน แล้วปรับขนาดให้เท่ากับปุ่มในรูป UI และไม่ต้องใส่สีเข้าไป “ โดยใช้เครื่องมือ Rectangle จากแทบเครื่องมือด้านซ้าย

    เมื่อเราสร้างสี่เหลี่ยมขึ้นมาจะมีแทบ Properties ด้านขวา ให้ทำการเอาติ๊กถูกหน้าช่องของ Fill และ Border ออก สี่เหลี่ยมสีขาวก็จะกลายเป็นสี่เหลี่ยมล่องหนไปทันใด เราจะทำแบบนี้กับปุ่มทุกปุ่มที่เราต้องการจะให้คลิกได้

    และขั้นตอนสุดท้าย นั้นคือการตั้งให้การคลิกสี่เหลี่ยมล่องหนนี้ทำอะไร เราจะทำผ่าน Tab ที่2 ชื่อ Prototype จากแถบ Menu Bar ข้างบน

    เมื่อกดเข้ามาใน Prototype Tab เราจะเห็นสี่เหลี่ยมล่องหนของเราถูก Highlight ด้วยสีฟ้าและมีลูกศรที่ด้านขวาของสี่เหลี่ยม ให้เราคลิกที่ลูกศร แล้วจะมีแถบด้านขวาขึ้นมาให้ตั้งค่าการ Interact

    ในส่วนของ Trigger ให้เลือกเป็น Tap นั้นก็คือการคลิกกล่องสี่เหลี่ยมดังกล่าว Type ให้เลือกเป็น Transition ในกรณีของการเปลี่ยนหน้า หรือเลือก Auto-Animate ในกรณีที่คลิกวัตถุนั้นแล้วมีการเปลี่ยนสถานะ

    Destination คือปลายทางที่จะไปนั้นก็คือ Artboard ที่เราวางรูปหน้า UI เอาไว้ เราสามารถเลือกได้จาก dropdown ได้เลย และอันสุดท้ายนั้นคือ Animation โดยทั่วไปจะเลือกเป็น Dissolve นั้นคือการสลับหน้าทั่วไปๆ มีหลายโหมดให้เล่น ลองดูได้ครับ

    เมื่อเชื่อมเสร็จก็จะมีลูกศรจากวัตถุของเราชี้ไปหา Artboard ปลายทาง เป็นอันเสร็จสิ้น

    แถม!! ในขั้นตอนการเชื่อมโยง Artboard เราสามารถคลิกค้างที่ลูกศรแล้วลากไปยัง Artboard ปลายทางได้เลย ไม่ต้องไป set จากแถบด้านขวาก็ได้

    จบกันไปที่เรียบร้อยสำหรับการทำ Prototype เบื้องต้นจากไฟล์ภาพ UI ที่มีอยู่แล้ว ยังมี Adobe Tips อื่นๆอีกมากมายให้ติดตามเร็วๆนี้ สำหรับบทความนี้หวังว่าทุกท่านจะสามารถนำไปประยุกต์ใช้ไม่มากก็น้อย สวัสดีครับ

  • Word : วิธีแก้ Repeat Header Table แล้ว word ดื้อ ไม่ยอม Repeat ให้

    เคยไหม กด ✔ ที่คำสั่ง Repeat as header row at the top of each page แล้ว ตารางนั้นก็ยังไม่ยอมแสดงหัวตารางในหน้าถัดไปเสียที

    ช่วงนี้หลังจากที่ผู้เขียนได้มีช่วงเวลาในการที่ปั่นเอกสาร รวมถึงเพื่อน ๆ ที่เจอปัญหาได้สอบถามกันเข้ามาเกี่ยวกับเรื่องนี้ ผู้เขียนจึงเห็นว่าน่าจะนำมาเขียน Blog เผื่อผู้อ่านท่านใดที่ติดปัญหาเช่นเดียวกัน จะได้ลองนำไปใช้ดูเผื่อแก้ปัญหาได้

    หลัก ๆ แล้วปกติ เมื่อผู้อ่านสร้างตารางขึ้นมา เมื่อต้องการให้ข้อมูลสองแถวแรกเป็นหัวตาราง ผู้เขียนจะทำการคลุมสองแถวนั้น จากนั้นคลิกเมาส์ขวา เลือกเมนู Table Properties… ดังภาพด้านล่าง

    จากนั้นที่ Tab Row ให้ ✔ ที่คำสั่ง Repeat as header row at the top of each page เพื่อเป็นการบอกว่า จะทำให้ตาราง 2 แถวแรกเป็นหัวตารางจากนั้นกด OK

    แต่เมื่อกลับมาหน้าตาราง ทำไมหัวตารางถึงยังไม่มีล่ะ????? 🤔

    งั้นต้องมาตรวจสอบเพิ่มเติมกันหน่อย โดยลองทำการคลุมสองแถวนั้นเหมือนเดิม จากนั้นคลิกเมาส์ขวา เลือกเมนู properties แต่ตอนนี้ไปเลือกที่ Tab Table สังเกตที่กลุ่ม Text wrapping ถ้าของผู้อ่านท่านใดเป็นแบบรูปด้านล่างคือเลือกอยู่ที่ Around นั่นคือปัญหา 😫😤

    ลองเปลี่ยนเป็นเลือก None ตามรูปด้านล่างดูค่ะ

    แทน แท๊นนนนนนนนนนนนนนนนน *0*

    ตารางของเรามีหัวตารางตามที่เราต้องการแล้ว เย้!!!!!!! 🎉🎊✨

    หวังว่าคงจะมีประโยชน์กับผู้อ่านไม่มากก็น้อยนะคะ สวัสดีค่าาาาา 😘

  • การเปลี่ยนแปลง Coded UI Test ใน Visual Studio 2019

    Microsoft ได้ประกาศว่า Visual Studio 2019 จะเป็น Visual Studio รุ่นสุดท้ายที่มีฟังก์ชัน Coded UI test

    ทำไมถึงเลิกใช้ Coded UI Test

    Coded UI tests ถูกใช้งานสำหรับการทดสอบการทำงานแบบอัตโนมัติของ web apps และ desktop apps โดยที่ในช่วงหลายปีหลังมานี้ Open source UI testing tools เช่น Selenium และ Appium ที่มีแรงสนับสนุนจาก community ที่เข้มแข็งและกลายเป็นมาตราฐานกลาง ซึ่ง Coded UI tests นั้นก็มีพื้นฐานอยู่บน Selenium นอกจากนี้ทั้ง Selenium และ Appium ยังทำงานข้ามแพลตฟอร์มและรองรับภาษาการเขียนโปรแกรมหลายภาษา

    Microsoft จะยังคงให้การสนับสนุน Coded UI tests ใน Visual Studio 2019 อย่างเต็มที่ในอีกหลายปีในอนาคต แต่จะจำกัดเฉพาะการแก้ไขข้อบกพร่อง จะไม่มีการเพิ่มคุณสมบัติใหม่ โดยที่เราสามารถติดตั้ง Visual Studio รุ่นต่าง ๆ แบบ side by side ซึ่งหมายความว่านักพัฒนาจะสามารถใช้ Visual Studio 2019 สำหรับการทดสอบ Coded UI test ที่มีอยู่ ในขณะที่สามารถใช้ Visual Studio รุ่นใหม่ในอนาคตสำหรับความต้องการการพัฒนาในแบบอื่น ๆ

    กลไกการติดตั้งแบบ side by side ทำให้ CI/CD pipelines  ทำงานได้อย่างราบรื่นโดยไม่หยุดชะงักในขณะที่เปลี่ยนแปลง นี่เป็นเพราะ Coded UI tests ทำงานเป็นส่วนหนึ่งของ CI/CD pipelines ใน Azure DevOps โดยการทดสอบจะทำงานกับ Visual Studio รุ่นใดรุ่นหนึ่งที่ติดตั้งใน agent หรือแพลตฟอร์มทดสอบรุ่นใดรุ่นหนึ่งโดยเฉพาะ  ซึ่งหมายความว่าเราไม่จำเป็นต้องใช้ Azure DevOps server สองรุ่นที่แตกต่างกันเพื่อให้สามารถทดสอบ Coded UI ที่มีอยู่ ในขณะที่มีการเปลี่ยนแปลง

    ทางเลือกที่แนะนำใช้แทน Coded UI Test

    Microsoft แนะนำให้ใช้ Open source UI testing tools Selenium และ Appium มาระยหนึ่งแล้ว ซึ่ง Visual Studio 2019 ถือเป็น Visual Studio รุ่นสุดท้ายที่มีฟังก์ชัน Coded UI test โดยที่ Microsoft แนะนำให้ใช้ Selenium สำหรับการทดสอบเ web application และAppium กับ WinAppDriver สำหรับการทดสอบ Desktop application (WPF, WinForms, Win32) และ UWP apps

    ไม่มีเครื่องมืออัตโนมัติที่จะช่วยย้ายจาก Coded UI test ไปยัง Selenium หรือ Appium ในขณะนี้ เราแนะนำให้การสร้าง unit test ใหม่ ควรใช้ทาง Selenium หรือ Appium ในขณะที่วางแผนการแทนที่ Coded UI test เก่าเป็น Selenium หรือ Appium ให้เสร็จสมบูรณ์ก่อนสิ้นสุดระยะเวลาการสนับสนุนจาก Visual Studio

    Selenium Browser Automation Project

    Selenium เป็นเครื่องมือและไลบรารี สำหรับใช้งานและสนับสนุนการทำงานอัตโนมัติของ web browser มันมีส่วนขยายที่จะจำลองการโต้ตอบของผู้ใช้กับ browser และโครงสร้างพื้นฐานสำหรับการใช้งานข้อกำหนด W3C WebDriver ที่ช่วยให้เราสามารถเขียนรหัสที่สามารถใช้ได้สำหรับ web browser หลักทั้งหมด

    ที่แกนกลางของ Selenium คือ WebDriver เป็น interface สำหรับเขียนชุดคำสั่งที่สามารถเรียกใช้ได้ในเบราว์เซอร์จำนวนมาก นี่ตัวอย่างของชุดคำสั่งแบบง่ายของ c#

    using System;
    using OpenQA.Selenium;
    using OpenQA.Selenium.Firefox;
    using OpenQA.Selenium.Support.UI;
    using SeleniumExtras.WaitHelpers;
    
    class HelloSelenium
    {
        static void Main()
        {
            using (IWebDriver driver = new FirefoxDriver())
            {
                WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
                driver.Navigate().GoToUrl("https://www.google.com/ncr");
                driver.FindElement(By.Name("q")).SendKeys("cheese" + Keys.Enter);
                IWebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("h3>div")));
                Console.WriteLine(firstResult.GetAttribute("textContent"));
            }
        }
    }  

    ในบทความต่อไป เราจะลงไปในรายละเอียดของสิ่งที่เกิดขึ้นเบื้องหลังเมื่อคุณเรียกใช้รหัสนี้ พร้องทั้งการติดตั้งและใช้ Selenium เป็นเครื่องมือทดสอบอัตโนมัติ

    อ้างอิง
    1. https://devblogs.microsoft.com/devops/changes-to-coded-ui-test-in-visual-studio-2019/
    2. https://selenium.dev/documentation/en/

  • Notebook Tips – ประหยัด ยืดอายุแบตเตอรี่

    มีคำถามมากมายเกี่ยวกับแบตเตอรี่ ไม่ว่าจะเป็นการชาร์จ, แบตเสื่อม ประหยัดแบต โน๊ตบุ๊คและอีกมากมาย เนื่องด้วยในบรรดาอุปกรณ์ภายในโน๊ตบุ๊คของเราส่วนมาก สิ่งที่จะมีปัญหาอันดันแรก นั้นก็คือแบตเตอรี่ ซึ่งหากใช้งานไม่ถูกต้อง ซื้อมาเพียงไม่กี่เดือนแบตก็เสื่อมแล้ว ทำให้เป็นปัญหาเวลาใช้นอกสถานที่เป็นอย่างมาก

    1.ปล่อยให้แบตเตอรี่หมดก่อนแล้วค่อยชาร์จ เรื่องความร้อนนั้นเป็นของคู่กับโน้ตบุ๊คด้วยเลยก็ว่าได้ ส่วนสำหรับแบตเตอรี่นั้นหากได้รับความร้อนนานๆ อายุก็จะสั้นลงแน่นอน แต่เอ๊ะ!! แล้วจะให้ทำยังไงหละในเมื่อการชาร์จทุกเครื่องมันก็ร้อนนิหน่า ถูกไหม? แต่มีวิธีแนะนำ นั้นก็คือ อย่าปล่อยให้แบตเตอรี่อยู่ต่ำกว่าประมาณ 20% ซึ่งถ้าจะให้ดีควรอยู่ในระดับ 20-30% หรืออาจจะ 40% ก็ได้ แต่ก็อย่าเกินนี้ เพราะยิ่งแบตเหลือน้อยมากๆ การชาร์จมันก็จะนาน ทำให้เกิดความร้อนมากกว่านั้นเอง และที่สำคัญอย่าให้แบตเตอรี่หรือตัวเครื่องโน้ตบุ๊คเราอยู่ใกล้กับสิ่งของร้อนๆ ด้วย

    2.ถอดแบตเตอรี่ออกขณะเล่นเกมหรือเวลาอยู่บ้าน ถามกันว่าต้องถอดแบตเตอรี่หรือเปล่า? ต้องใส่ไว้ตลอดไหม? วันนี้ก็มีคำตอบให้ หากเราถอดไว้แล้ว แต่เกิดปัญหา ไฟดับ ไฟกระชาก มันก็อาจจะทำให้อุปกรณ์หรือโน้คบุ๊คของเราเสียหายได้ครับ ซึ่งอันที่จริงหากเราถอดแบตเตอรี่ออกมามันจะช่วยให้ยืดอายุการใช้งานได้จริง แต่มันก็เพียงเล็กน้อย แล้วมันจะคุ้ม? กับสิ่งที่เราอาจจะเสียไป ดูแล้วมันก็คงได้ไม่คุ้มเสีย

    3.ถอดแบตเตอรี่เก็บไว้ ไม่ต้องใช้ ไม่เสื่อม ปกติแบตเตอรี่ อายุประมาณ 1 ปีหรืออาจจะน้อยหรือมากกว่า ตามลักษณะการใช้งาน เราก็เริ่มเห็นปัญหาแบตเตอรี่เสื่อมแล้ว ใช้งาน 1 ปีเต็มพอดี แบตก็ใช้งานได้สั้นลง 30 นาที จากปกติใช้ได้ 3 ชั่วโมง ตอนนี้ก็เหลือ 2 ชั่วโมง 30 นาทีโดยประมาณ ใช้ถูกหลักบ้างไม่ถูกหลักบ้างตามสถานะการ และแต่ส่วนใหญ่แล้วแบตเตอรี่มักจะสิ้นใจก่อนโน้ตบุ๊คของเราอยู่แล้ว โดยปกติก็ โน้ตบุ๊ค 1 เครื่อง กับ แบตเตอรี่ 2 ลูก ก็ถือว่ากำลังดี ก็คือใช้ตัวที่แถมมา และเราก็เปลี่ยนหนึ่งครั้ง มันก็จะสิ้นอายุไขของมัน หรือบางท่านก็อาจจะใช้แบตเตอรี่ลูกเดียวแบบนี้ก็ถือว่าคุ้มค่ามาก

    เพิ่มชั่วโมงการทำงานของโน้ตบุ๊ตบนแบตเตอรี่ โดยไม่ต้องเสียสตางค์

    วิธีพื้นฐานคลาสสิคยิ่งนัก โดยเจ้า Windows Power Manager นั้นจะมีติดตั้งมาให้บนโน้ตบุ๊คทุกตัว(ที่ใช้ Windows) โดยวิธีที่ง่ายที่สุดที่ไม่ต้องปรับแต่งอะไรเลยก็คือเลือกปรับให้มันเป็น Power Saver นั่นเอง แต่ระดับสมาชิก NBS คงไม่ทำอะไรง่ายๆ  ซึ่งมันก็มีวิธีแอดวานซ์กว่านั้น ก็คือให้สังเกตเครื่องหมายรูปถ่านที่ Task Bar > คลิกซ้าย เลือก More Power Option > Change Plan Setting > Change Advance Power Option ที่นี้มันก็จะขึ้นหน้าต่าง Power Option

    หัวข้อที่แนะนำให้ปรับถ้าต้องการใช้แบตเตอรี่โน้ตบุ๊คนานๆ ก็จะ Processor ให้ Maximize อยู่ที่ราวๆ 50% ก็จะช่วยประหยัดไฟได้พอสมควร โดยที่ประสิทธิภาพของเครื่องไม่ตกลงมากนัก การบล๊อกแฟลชโฆษณาต่างๆ และปิดโปรแกรมที่ไม่จำเป็นหรือปิด (Disable) Wireless / Bluetooth รวมถึง การลดความสว่างของหน้าจอ ก็ล้วนแต่มีส่วนช่วยให้ใช้งานได้ยาวนานขึ้น

    การ Calibrate Battery เพื่อเพิ่มอายุการใช้งาน เมื่อแบตเตอรี่โน้ตบุ๊กเสื่อมทำไงดี ?

    สำหรับผู้ที่ใช้โน้ตบุ๊คมาสักปี 2 ปีปัญหาหนึ่งที่มักจะเจอกันก็คือแบตเตอรี่เสื่อม?ซึ่งถ้าใช้เครื่องมาระดับนี้การเสื่อมของแบตเตอรี่ถือเป็นเรื่องปรกติ แม้ท่านจะทำวิธีใดก็ตามแบตเตอรี่ที่ท่านใช้ๆอยู่ก็ย่อมต้องเสื่อมไปตามการเวลาเป็นปรกติ หลายๆท่านอาจจะเลือกที่จะต่อ Adapter ตลอดเวลา หรือไม่ก็ซื้อเครื่องใหม่ไปเลย แต่อีกหลายๆท่านก็ยังจำเป็นต้องใช้แบตเตอรี่อยู่ (และก็ไม่มีตังซื้อเครื่องใหม่) การซื้อแบตเตอรี่ใหม่จึงเป็นทางเลือกที่น่าสนใจเพราะราคาถูกกว่าซื้อเครื่องใหม่ และก็ทำให้โน้ตบุกใช้งานแบตเตอรี่ได้เหมือนเดิมปัจจุบันแบตเทียบก็ถือเป็นตัวเลือกที่น่าสนใจสำหรับผู้ที่งบประมาณจำกัด แต่อยากเปลี่ยนแบตเตอรี่ก้อนเก่าที่เสื่อมแล้วเป็นแบตตัวใหม่ใสปิ้ง อีกทั้งปัจจุบันผู้ผลิตแบตเตอรี่เทียบหลายๆเจ้าก็พยายามพัฒนาคุณภาพให้เทียบเท่าแบตแท้จากผู้ผลิตโน้ตบุ๊ก โอกาสที่แบตเทียบจะมีปัญหาใช้งานได้ไม่เต็มที่หรือแบตเตอรี่ระเบิดก็มีโอกาสน้อย เพียงแต่ว่าเราต้องดูชื่อผู้ผลิตหรือนำเข้าให้มันใจ ยิ่งถ้าเป้นแบรนด์ที่ขายมานานหรือเป็นที่รู้จักก็จะช่วยให้เรามั่นใจขึ้น

    วิธีการประหยัดพลังงานให้แบตเตอร์รี่โน้ตบุ๊ก

    เครื่องโน้ตบุ๊กตัวโปรดของคุณจะกลายเป็นภาระอันใหญ่หลวงทันที ถ้าหากเราต้องมัวแต่วิ่งหาปลั้กไฟเพราะว่าแบตหมดก่อนเวลาอันควรเอาซะดื้อๆ ต่อไปนี้จะเป็น  วิธีการที่เราอยากจะแนะนำ เพื่อจะทำให้เครื่องโน้ตบุ๊กของคุณสามารถประหยัดพลังงาน และใช้งานแบตเตอร์รี่ของคุณเพิ่มเติมได้อีกหลายนาที

    1.จัดเรียงข้อมูลในฮาร์ดดิสก์อย่างสม่ำเสมอ ฮาร์ดดิสก์เป็นจุดที่ทำงานช้าและใช้พลังงานมากที่สุดจุดหนึ่งของเครื่องโน้ตบุ๊ก ยิ่งเราสามารถทำให้ฮาร์ดดิสก์ของเราทำงานได้ไวมากขึ้นเท่าไร ความต้องการที่จะใช้พลังงานก็จะน้อยลงเท่านั้น วิธีการหนึ่งที่ทำให้เครื่องทำงานได้เต็มประสิทธิภาพอยู่เสมอ ก็คือการ Defragment หรือจัดเรียงข้อมูลในฮาร์ดดิสก์นั้นเอง

    2.ปิดโปรแกรมที่ทำงานอยู่ด้านหลังออกไปบ้าง หากคุณเป็นคนที่ไม่ค่อยสนใจอะไรเวลาลงโปรแกรมล่ะก็ คุณจะได้โปรแกรมที่แอบทำงานอยู่เงียบๆ อยู่ข้างหลังตามมาเป็นว่าเล่น โปรแกรมพวกนี้ชอบถูกสั่งให้เปิดขึ้นมารอการใช้งานพร้อมกับ Windows ตั้งแต่แรก นั้นเป็นสาเหตุที่ทำให้เครื่องคอมพิวเตอร์ของคุณบูตช้าลงทุกวันๆ

    3.ดึงอุปกรณ์ภายนอกที่ไม่ได้ใช้ออก อุปกรณ์ USB ทั้งหลายแหล่ที่คุณเสียบทิ้งไว้กับเครื่อง จะดึงพลังงานออกไปจากแบตอยู่เสมอ ไม่ว่าจะมากหรือน้อยก็ตาม แม้แต่เม้าส์และตัว WiFi ถ้าหากคุณไม่ได้ใช้งานก็ควรจะปิด เพื่อให้เครื่องตัดกระแสไฟออกไป4.เพิ่มหน่วยความจำให้พอต่อการใช้งาน ยิ่งเครื่องมีแรมมากพอจะให้โปรแกรมใช้เท่าไร โอกาสที่โปรแกรมจะไปใช้ Virtual Memory จะลดลง ส่วน Virtual Memory คืออะไรนั้น ถ้าพูดง่ายๆ มันคือแรมที่ถูกจำลองขึ้นมาบนฮาร์ดดิสก์เพราะว่าแรมจริงนั้นมีไม่พอที่จะใช้ทำงาน และอย่างที่เราบอกไปในข้อแรมว่า ฮาร์ดดิสก์ทำงานช้าและใช้พลังงานเยอะมาก

    4.เพิ่มหน่วยความจำให้พอต่อการใช้งาน ยิ่งเครื่องมีแรมมากพอจะให้โปรแกรมใช้เท่าไร โอกาสที่โปรแกรมจะไปใช้ Virtual Memory จะลดลง ส่วน Virtual Memory คืออะไรนั้น ถ้าพูดง่ายๆ มันคือแรมที่ถูกจำลองขึ้นมาบนฮาร์ดดิสก์เพราะว่าแรมจริงนั้นมีไม่พอที่จะใช้ทำงาน และอย่างที่เราบอกไปในข้อแรมว่า ฮาร์ดดิสก์ทำงานช้าและใช้พลังงานเยอะมาก

    อ้างอิง : https://notebookspec.com/web/category/tips-tricks/

  • แนวทางการเขียน Unit Tests ที่ดีสำหรับ C # (2)

    ในบทความก่อนหน้า ได้พูดถึงการเลือก Testing framework ที่เหมาะสม การเขียน unit test โดยใช้แนวคิดแบบ “AAA” (Arrange, Acr, Assert) และการกำหนดชื่อ method ที่สื่อความหมายเข้าใจได้ง่าย

    Test Initialize & Cleanup

    เมื่อ unit tests ทำการทดสอบ methods ภายใน class ก็จำเป็นต้องสร้าง instance ของ class นั้นๆขึ้นมาก่อน ซึ่งจะเกิดขึ้นหลายๆครั้งใน unit test เพื่อประหยัดเวลาและทรัพยากรของระบบ เราสามารถใช้ [TestInitialize] attribute ของ MSTest เพื่อบอกว่า method นั้นใช้สำหรับกำหนดค่าเริ่มต้น สร้าง instance ของ class ก่อนที่จะเริ่ม run unit tests (หรือ [SetUp] ใน NUnit หรือถ้าใช้ xUnit.net ให้สร้างใน constructor )

    เมื่อการทดสอบจบลง เราจะต้องทำการ cleanup object ต่างๆที่ใช้ในการทดสอบ โดยการใช้ [TestCleanup] attribute ในกรณีที่ใช้ MSTest ([TearDown ใน NUnit หรือ implement IDisposable interface สำหรับกรณีที่ใช้ xUnit.net)

    ตัวอย่างด้านล่าง จะกำหนดให้ method “Initialize” เป็น method ที่ใช้สำหรับสร้าง instance ของ class ที่จะใช้ในการทดสอบ ซึ่งจะถูกเรียกใช้ก่อนการทดสอบจะเริ่มทำงาน

    ILogger _log;
    ICalc _calc;
    
    [TestInitialize]
    public void Initialize()
    {
    	_log = Mock.Of<ILogger<Calc>>();
    	_calc = new Calc(_log);
    }
    
    [TestMethod]
    public void Divide_ShouldThrowArgumentException_IfDivideByZero()
    {
    	double result = _calc.Divide(10, 5);
    	result.ShouldBe(2);
    }
    
    [TestCleanup]
    public void Cleanup()
    {
    	// Optionally dispose or cleanup objects
            _calc = null;
    	...
    }

    Shouldly Assertion Framework

    Shouldly framework จะช่วยให้ unit test ทำได้ง่ายและเข้าใจได้ง่ายขึ้น มันจะช่วยผู้พัฒนาในการเขียนการยืนยันผลการทำงานของ unit tests ซึ่งเมื่อกลับมาดู unit test อีกครั้งสามารถอ่าน code แล้วเข้าใจวัตถุประสงค์และความคาดหวังของการทดสอบ

    เปรียบเทียบความแตกต่างระหว่าง การใช้ Shouldly กับ ไม่ใช่ Shouldly

    With Shouldly

    result.ShouldBe(2);

    Without Shouldly

    Assert.AreEqual(2, result);

    Shouldly สามารถใช้ในการตรวจสอบ exception ว่าเกิดตามที่คาดหวังไว้หรือไม่ และสามารถตรวจสอบ meesage ของ exception ได้

    [TestMethod]
    public void Divide_ShouldThrowArgumentException_IfDivideByZero()
    {
    	Should.Throw<ArgumentException>(() => _calcs.Dicide(10, 0))
    	      .Message
                  .ShouldBe("Divide by zero.");
    }

    Moq Mocking Framework

    การสร้าง object จำลองสำหรับ object ที่ไม่ใช่ object หลักที่จะทำการทดสอบ แทนที่การเรียกใช้ object จริงๆ เช่น logging utility หรือ database จะทำให้การทดสอบทำได้อย่างมีประสิทธิภาพขึ้น ซึ่งการทำแบบนี้ เราต้องใช้ Mocking framework มาช่วย โดยตัวที่ได้รับความนิยมตัวนึงก็คือ Moq framework

    การใช้ Moq framework จะช่วยให่เราสามารถ mock class ต่างๆโดยใช้เพียง interface. ตัวอย่างเช่น การใช้ mock ของ logging utility ใน unit test แทนที่จะสร้างและเรียกใช้ logging utility ตัวจริง

    ILogger log = Mock.Of<ILogger<Calc>>();

    We can also verify if a mock object was invoked inside a method and the amount of times it was invoked:

    [TestMethod]
    public void Divide_LogInformationMethod()
    {
    	ILogger log = Mock.Of<ILogger<Calc>>();
    	ICalc calc = new Calc(log);
    	double result = calc.Divide(10,5);
    	Mock.Get(log).Verify(x => x.Log(
    		LogLevel.Information, 
        	It.IsAny<EventId>(), 
        	It.IsAny<FormattedLogValues>(), 
        	It.IsAny<Exception>(), 
        	It.IsAny<Func<object, Exception, string>>()), 
        	Times.Once);
    }

    อ้างอิง : https://kiltandcode.com/2019/06/16/best-practices-for-writing-unit-tests-in-csharp-for-bulletproof-code/

  • แนวทางการเขียน Unit Tests ที่ดีสำหรับ C #

    ในความคิดของผู้เขียน ผู้พัฒนาส่วนใหญ่มักไม่ชอบที่จะเขียน Unit testing บางคนอาจจะคิดว่ามันน่าเบื่อ หรือบางคนก็ไม่เห็นคุณค่าในการเขียน code เพื่อตรวจสอบการทำงานของ code อื่นๆ

    Unit testing คือแนวทางในการเขียน code เพื่อตรวจสอบว่าหน่วยการทำงานใน แอปพลิเคชันซอฟต์แวร์ ว่าทำงานตามที่ตั้งใจไว้หรือไม่ เช่น หากตั้งใจที่จะให้ตัวอักษรตัวแรกของคำเป็น พิมพ์ใหญ่ unit test จะต้องสามารถตรวจสอบว่าตัวอักษรตัวแรกเป็นตัวพิมพ์ใหญ่โดยไม่สนใจอักษรตัวอื่นๆ

    ข้อดีอย่างหนึ่งของการเขียน unit tests ใน C # คือ เราสามารถใช้ Test Explorer ใน Visual Studio เพื่อตรวจสอบว่าการทดสอบทั้งหมดผ่านหรือไม่ โดยที่ไม่ต้องกังวลว่าการเปลี่ยนแปลงล่าสุดที่เขียน จะทำให้ระบบทำงานไม่ได้หรือไม่

    การเลือก Testing Framework

    Testing frameworks ช่วยให้เราสามารถใช้ attribute ในการเขียน unit tests [TestClass] หรือ [TestMethod] ซึ่ง attribute เหล่านี้บอกให้ Text Explorer ใน Visual Studio รู้จัก class หรือ method นั้นคือ unit test และจะรันโค้ดเพื่อตรวจสอบการทำงานว่าผ่านหรือไม่ผ่าน

    Testing frameworks สำหรับ. NET ที่ได้รับความนิยมคือ

    • MSTest
    • xUnit.NET
    • NUnit

    การเลือก Testing frameworks ก็เหมือนกับการเลือกรถ บางอันมีประสิทธิภาพสูง บางอันให้ความสะดวกสบาย แต่สุดท้ายทั้งหมดก็ทำงานเพื่อบรรลุเป้าหมายเดียวกัน

    NUnit เป็น test framework แรกๆที่ได้รับความนิยมสำหรับผู้พัฒนา .NET, เมื่อเปรียบเทียบกับความสามารถของ MSTest ( test framework ของ Microsoft) โดยส่วนใหญ่ก็จะเหมือนกับใน NUnit และ MSTest เป็น test framework ที่ถูกสร้างขึ้นและสามารถใช้งานได้ใน Visual Studio สำหรับ xUnit.NET เป็นน้องใหม่ใน test framework ที่นำเสนอคุณสมบัติเพิ่มเติมและวิธีการที่ง่ายขึ้นในการเขียน unit tests ที่พัฒนาโดย NET Core

    โดยส่วนใหญ่จะไม่ใช้เวลามากเกินไปในการพิจารณา test framework เพื่อใช้ในโครงการหากโครงการมีการกำหนด test framework ที่เฉพาะเจาะจง ก็ให้ใช้ test framework นั้น ถ้าไม่ได้กำหนด ก็ให้ทำการศึกษาและตัดสินใจเลือก test framework ที่เหมาะกับโครงการ

    AAA ( Arrange, Act, Assert )

    วิธีการเขียน unit test แบบ ‘AAA’ (Arrange, Act, Assert) เป็นวิธีปฏิบัติในการเขียน unit test และช่วยให้เราสามารถเขียน unit test ในรูปแบบที่ทำซ้ำและเข้าใจได้

    Arrange

    เราจะเริ่มเขียน unit test โดยการจัดเรียง objects ที่ต้องการทดสอบ ซึ่งอาจจะเป็นการ initializing class หรือ การเตรียมข้อมูลในฐานข้อมูลสำหรับทดสอบ หรือการ mocking object โดยการใช้ interface

    ตัวอย่างด้านล่าง มีกำหนดค่า mock object ของ ILogger<Calc> ให้กับ interface “ILogger”

    // Arrange
    ILogger log = Mock.Of<ILogger<Calc>>();
    ICalc calc = new Calc(log);

    Act

    เราจะดำเนินการ และเรียกใช้ส่วนของ code หรือ method ที่ต้องการทดสอบโดยการผ่านค่า parameter ให้กับ method และเก็บผลลัพธ์ใน valiable ที่กำหนด

    ตัวอย่างด้านล่าง เป็นการเรียกใช้ method “Divide” โดยส่ง parameter ไป 2 ตัว และเก็บผลลัพธ์การทำงานในตัวแปร result

    // Act
    int result = calc.Divide(10, 5);

    Assert

    สุดท้าย จะเป็นการยืนยันว่าผลลัพธ์ที่ได้จากการทดสอบเป็นไปตามที่ได้คาดหวังไว้หรือไม่

    ตัวอย่างด้านล่าง ตัวแปร “result” ควรที่จะมีค่าเท่ากับ 2

    // Assert
    Assert.AreEqual(2, result);

    การตั้งชื่อ

    เมื่อแนวคิดของ ‘AAA’ เป็นแนวปฏิบัติที่ได้รับความนิยม แต่ในส่วนของการกำหนดชื่อของ method ยังคงแตกต่างกันไปและขึ้นอยู่กับผู้พัฒนา ทีม และองค์กร ซึ่งการกำหนดแนวทางการตั้งชื่อเพื่อใช้กับ unit tests ให้มีความสอดคล้องและความชัดเจน ไปในทางเดียวกัน เป็นความคิดที่ดี ซึ่งการตั้งชื่อควรประกอบไปด้วย

    • method ที่ทดสอบ (เช่น ‘Add’)
    • คำอธิบายสั้น ๆ เกี่ยวกับการทดสอบ (เช่น ‘ShouldThrowArgumentException’)
    • ความคาดหวังของการทดสอบนี้ (เช่น ‘IfDivideByZero’)
    public void Divide_ShouldThrowArgumentException_IfDivideByZero()
    {
        ...
    }

    การกำหนดชื่อในรูปแบบนี้ จะเหมาะสำหรับการดูใน Text Explorer ซึ่งสามารถติดตามและเข้าใจได้อย่างง่ายดายว่า unit tests แต่ละหน่วยคืออะไรโดยไม่ต้องเปิดการทดสอบหน่วย

    แนวทางการเขียน Unit Tests ที่ดีสำหรับ C # ยังไม่หมดเพียงเท่านี้ ในบทความต่อไป เราจะมาดูการทำ Test Initialize & Cleanup และ ตัวช่วยอื่นๆที่ใช้ในการเขียน unit tests

    อ้างอิง : https://kiltandcode.com/2019/06/16/best-practices-for-writing-unit-tests-in-csharp-for-bulletproof-code/

  • เขียน Unit test ทดสอบการทำงานกับฐานข้อมูลที่ใช้ Entity Framework Core

    ในบทความนี้ จะนำเสนอการเขียน unit test เพื่อทดสอบการทำงานของ method ที่ใช้งาน Entity Framework Core ซึ่งตัว Entity Framework Core มาพร้อมความสามารถที่สามารถใช้งาน in-memory store ซึ่งสามารถใช้ในการทดสอบได้ หรือจะใช้ mock framework ในการทดสอบก็ได้ โดยในบทความนี้จะแสดงให้เห็นทั้งสองแนวทาง

    In Memory Database

    In Memory Database เป็นการสร้าง database จำลองขึ้นมาใช้บน memory แทนที่การใช้ database ตัวจริง ทำให้เราสามาถเขียน unit test โดยที่ไม่ไปกระทบกับ database จริงๆ โดยการเพิ่ม Microsoft.Entityframework.InMemory NuGet package เข้าไปใน test projet

    ในส่วนของ DbContext class จะต้องมี constructor ที่รับ DbContectOption เป็น parameter

    var options = new DbContextOptionsBuilder<MyDbContext>()
                    .UseInMemoryDatabase(Guid.NewGuid().ToString("N")).Options;
    
    var dbContext = new MyDbContext(options);

    จากตัวอย่างด้านบน เราใช้ UseInMemoryDatabase extension method -ของ DbContextOptionsBuilder ซึ่งรับ parameter 1 ตัวเพื่อกำหนดชื่อของ database โดยเราจะใช้ Guid จากนั้นก็สามารถเขียน unit test ได้ดังนี้

    [TestClass]
    public class MyRepositoryTest
    {
            private MyDbContext CreateDbContext()
            {
                var options = new DbContextOptionsBuilder<MyDbContext>()
                    .UseInMemoryDatabase(Guid.NewGuid().ToString("N")).Options;
    
                var dbContext = new MyDbContext(options);
                return dbContext;
            }
    
           
            [TestMethod]
            public void It_should_add_a_product_successfully()
            {
                //Arrange
                var dbContext = CreateDbContext();
                var rep = new MyRepository(dbContext);
                var product = new Product 
                { 
                   ProductName="Toyota Altis",
                   UnitPrice=900000 
                };
    
                //Act
                var result = rep.Add(product);
               
                //Assert
                Assert.IsTrue(result.ProductID > 0);
    
                //Clean up
                dbContext.Dispose();
            }
    
            [TestMethod]
            public void It_should_update_a_product_successfully()
            {
                //Arrange
                var expected = 950000;
                var dbContext = CreateDbContext();
                var rep = new MyRepository(dbContext);
                var product = new Product 
                { 
                   ProductName="Toyota Altis",
                   UnitPrice=900000 
                };
    
                //Act
                var result = rep.Add(product);
                result.UnitPrice = expected;
                rep.Update(result);
                result = dbContext.Products.First(p=>p.ProductID == result.ProductID);
    
                //Assert
                Assert.AreEqual(expected,result.UnitPrice);
    
                //Clean up
                dbContext.Dispose();
            }
    
            [TestMethod]
            public void It_should_remove_a_product_successfully()
            {
                //Arrange
                var dbContext = CreateDbContext();
                var rep = new MyRepository(dbContext);
                var product = new Product 
                { 
                   ProductName="Toyota Altis",
                   UnitPrice=900000 
                };
    
                //Act
                var result = rep.Add(product);
                rep.Delete(result.ProductID);
                var isExists = dbContext.Products.Any(p => p.ProductID == result.ProductID);
    
                //Assert
                Assert.IsFalse(isExists);
    
                //Clean up
                dbContext.Dispose();
            }
    
        }

    จากตัวอย่างด้านบน CreateDbContext method ทำหน้าที่ในการสร้าง DbContext object ที่ทำงานกับ in-memory database แทนที่จะใช้งาน database ตัวจริง หลังจากนั้นก็สามารถทำตามที่ต้องการได้ เหมือนกับการใช้งาน DbContext ปกติ

    Using Mock Frameworks

    อีกทางเลือกหนึ่ง เราสามารถใช้ mock frameworks ในการเขียน unit tests ซึ่งเราจะใช้ Moq mock frameworks ซึ่งเป็น mock frameworks ที่ได้รับความนิยมสำหรับ .Net platform โดยก่อนที่จะเริ่มเขียน unit test เราจะต้องกำหนดให้ DbSet pproperty ของ DbContext เป็น virtual ซึงจะทำให้ Moq framework สามารถสร้าง fake object และ override property นี้ได้ และดำเนินการดังนี้

    1. สร้าง generic collection สำหรับ DbSet property แต่ละตัว
    2. Config fake DbSet ใน mock framework
    3. Setup และ forward DbSet property เหล่านั้นไปที่ generic collection
      • Provider
      • Expression
      • ElementType
      • GetEnumerator()
    [TestClass]
    public class MyRepositoryTest
    {
            private DbSet<T> CreateDbSet<T>(IQueryable<T> collection) where T:class
            {
                var stubDbSet = new Mock<DbSet<T>>();
                stubDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(collection.Provider);
                stubDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(collection.Expression);
                stubDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(collection.ElementType);
                stubDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(collection.GetEnumerator());
                return stubDbSet.Object;
            }
    
            [TestMethod]
            public void list_all_available_products_from_the_data_store()
            {
                //Arrange
                var expected = new List<Product>
                {
                    new Product {ProductName ="Toyota yaris"},
                    new Product {ProductName ="Toyota altis"},
                    new Product {ProductName ="Toyota camry"}
                };
    
                var productDbSet = CreateDbSet(expected.AsQueryable());
    
                var stubContext = new Mock<MyDbContext>();
                stubContext.Setup(o=>o.Products).Returns(productDbSet);
                var rep = new MyRepository(stubContext.Object);
    
                //Act
                var actual = (List<Product>)rep.GetAll();
    
                //Assert
                CollectionAssert.AreEquivalent(expected, actual);
    
            }
    
    
            [TestMethod]
            public void return_a_product_for_given_product_id()
            {
                //Arrange
                var expected = "Toyota altis";
                var expected = new List<Product>
                {
                    new Product {ProductName ="Toyota yaris"},
                    new Product {ProductName ="Toyota altis"},
                    new Product {ProductName ="Toyota camry"}
                };
    
                var productDbSet = CreateDbSet(collection.AsQueryable());
    
                var stubContext = new Mock<MyDbContext>();
                stubContext.Setup(o => o.Products).Returns(productDbSet);
                var rep = new MyRepository(stubContext.Object);
    
                //Act
                var actual = rep.GetById(2);
    
                //Assert
                Assert.AreEqual(expected, actual.ProductName);
    
            }        
        }

    อ้างอิง : https://www.bitiniyan.com/2019/02/02/how-to-write-unit-tests-with-entity-framework-core/