单元测试的艺术 -- 系列文章(附测试代码)

 

 

出处 :https://www.cnblogs.com/edisonchou/category/821397.html

===============================================================

自测试使用的测试代码,供参考:

LogAN.Lib类库:

MyMath相关类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogAN.Lib
{
    public interface IMyMath
    {
        void Test1(string s);

        int Add(int x, int y);
    }

    public class MyMath : IMyMath
    {
        public void Test1(string s)
        {
            System.Diagnostics.Debug.WriteLine($"==============={s}");
            //throw new Exception();
        }

        public int Add(int a, int b)
        {
            return a + b;
        }

    }
}
View Code

LogAnalyzer相关类

/********************************************************************************
 * File Name    : LogAnalyzer
 * Create Time  : 2020-07-06 10:47:15
 * Description  : 
 * Remark       : 
 * 
 * 
 ********************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LogAN.Lib
{

    public interface ILogger
    {
        void LogError(string message);
    }

    public interface IWebService
    {
        void Write(string message);
    }

    public class LogAnalyzer
    {
        private ILogger _logger;
        private IWebService _webService;

        public LogAnalyzer()
        { }

        public LogAnalyzer(ILogger logger, IWebService webService)
        {
            _logger = logger;
            _webService = webService;
        }


        public bool IsValidLogFileName(string fileName)
        {
            if (!fileName.EndsWith(".log", StringComparison.CurrentCultureIgnoreCase))
            {
                return false;
            }
            return true;
        }


        public int MinNameLength { get; set; }

        public void Analyze(string fileName)
        {
            if (fileName.Length < MinNameLength)
            {
                try
                {
                    _logger.LogError(string.Format("Filename too short : {0}", fileName));
                }
                catch (Exception ex)
                {
                    _webService.Write("Error From Logger : " + ex.Message);
                }
            }
        }
    }
}
View Code

 DateTimeHelper类

namespace LogAN.Lib
{
    public static class DateTimeHelper
    {
        public static bool IsTodayLastDateOfYear()
        {
            DateTime today = DateTime.Now;
            if (today.Month == 12 && today.Day == 31)
                return true;
            else
                return false;
        }
    }
}
View Code

 

LogAN.Lib.Tests类库

MyMathTests.cs

namespace LogAN.Lib.Tests
{
    using NSubstitute;

    [TestClass()]
    public class MyMathTests
    {

        [TestMethod]
        public void TestClass1Test()
        {
            IMyMath c = NSubstitute.Substitute.For<Lib.IMyMath>();
            c.When(x => { x.Test1(Arg.Any<string>()); })
                .Do(context => throw new ArgumentNullException("aa"));
            //c.Received().Test1("");
            Assert.ThrowsException<ArgumentNullException>(() => { c.Test1(""); });
        }

        [TestMethod()]
        public void Test1Test()
        {
            var c = Substitute.For<MyMath>();
            c.Test1("");
            Assert.IsFalse(false);
        }

        [TestMethod()]
        [DataRow(2, 4, 6)]
        [DataRow(-3, 6, 3)]
        [DataRow(-3, 0, -3)]
        public void AddTest(int a, int b, int res)
        {
            var c = Substitute.For<MyMath>();
            var r1 = c.Add(a, b);
            Assert.AreEqual(r1, res);
        }

        [TestMethod]
        public void AddTest_InterfaceAdd_return()
        {
            var c = Substitute.For<IMyMath>();
            c.Add(2, 4).Returns(11);
            var r1 = c.Add(2, 4);
            Assert.AreEqual(c.Add(2, 4), 11);
        }

    }
}
View Code

 

LogAnalyzerTests.cs

namespace LogAN.Lib.Tests
{
    using NSubstitute;

    [TestClass()]
    public class LogAnalyzerTests
    {

        [TestMethod]
        [TestCategory("aaa")]
        public void IsValidLogFileNameTest_BadExtension_ReturnFalse()
        {
            LogAnalyzer analyzer = new LogAnalyzer();
            bool result = analyzer.IsValidLogFileName("filewithbadextension.foo");
            Assert.AreEqual(false, result);
        }

        [TestCategory("aaa")]
        [TestMethod]
        public void IsValidFileName_GoodExtensionLowercase_ReturnsTrue()
        {
            LogAnalyzer analyzer = new LogAnalyzer();
            bool result = analyzer.IsValidLogFileName("filewithbadextension.log");
            Assert.AreEqual(true, result);
        }

        [TestMethod()]
        public void IsValidFileName_GoodExtensionUppercase_ReturnsTrue()
        {
            LogAnalyzer analyzer = new LogAnalyzer();
            bool result = analyzer.IsValidLogFileName("filewithbadextension.LOG");
            Assert.AreEqual(true, result);
        }


        [TestMethod()]
        public void Analyze_LoggerThrows_CallsWebService()
        {
            var mockWebService = Substitute.For<IWebService>();
            var stubLogger = Substitute.For<ILogger>();
            // 无论输入什么都抛出异常
            stubLogger.When(logger => logger.LogError(Arg.Any<string>()))
                .Do(info => { throw new Exception("fake exception"); });

            var analyzer = new LogAnalyzer(stubLogger, mockWebService);
            analyzer.MinNameLength = 10;
            analyzer.Analyze("short.txt");
            //验证在测试中调用了Web Service的模拟对象,调用参数字符串包含 "fake exception"
            mockWebService.Received().Write(Arg.Is<string>(s => s.Contains("fake exception")));
        }

        /// <summary>
        /// 使用 Microsoft Fakes 进行单元测试,调用自己的存根(Fake的对象)
        /// </summary>
        [TestMethod]
        public void Analyze_MSstub_CallsLogErrorString()
        {
            var log_x = "";
            var log = new Fakes.StubILogger();// { LogErrorString = (x) => { log_x = x; } };
            log.LogErrorString = (x) => { log_x = x; };
            var web = new Lib.Fakes.StubIWebService();
            var an = new Lib.LogAnalyzer(log, web);
            an.MinNameLength = 10;
            an.Analyze("kkkk.txt");

            Assert.IsTrue(log_x.Contains("kkkk"));

        }

        /// <summary>
        /// 使用 Microsoft Fakes 进行单元测试,模拟异常
        /// </summary>
        [TestMethod]
        public void Analyze_MSstub_CallsWebService()
        {
            var logMsg = "";
            var log = new Fakes.StubILogger();// { LogErrorString = (x) => { log_x = x; } };
            log.LogErrorString = (x) => { logMsg = x; };
            log.LogErrorString = (x) => { throw new Exception("aaaaaaa"); };

            var webMsg = "";
            var web = new Lib.Fakes.StubIWebService();
            web.WriteString = (x) => { webMsg = x; };
            var an = new Lib.LogAnalyzer(log, web);
            an.MinNameLength = 10;
            an.Analyze("kkkk.txt");

            Assert.IsTrue(webMsg.Contains("aaaaaaa"));
            //Assert.IsTrue(logMsg.Contains("kkkk"));
        }

    }
}
View Code

 

DateTimeHelperTests.cs

namespace LogAN.Lib.Tests
{
    using Microsoft.QualityTools.Testing.Fakes;
    using System.Fakes;

    [TestClass()]
    public class DateTimeHelperTests
    {


        [TestMethod]
        public void TestTodayIsLastDateOfYear()
        {
            // Arrange

            // Act
            bool result = false;
            using (ShimsContext.Create())
            {
                ShimDateTime.NowGet = () => new DateTime(2013, 12, 31);
                result = DateTimeHelper.IsTodayLastDateOfYear();
            }

            // Assert
            Assert.IsTrue(result);
        }

        [TestMethod]
        public void TestTodayIsNotLastDateOfYear()
        {
            // Arrange

            // Act
            bool result = false;
            using (ShimsContext.Create())
            {
                ShimDateTime.NowGet = () => new DateTime(2013, 12, 9);
                result = DateTimeHelper.IsTodayLastDateOfYear();
            }

            // Assert
            Assert.IsFalse(result);
        }
    }
}
View Code

 

说明:其中部分使用了Microsoft Fakes写的测试代码,请参考:使用 Microsoft Fakes 进行单元测试

posted on 2020-06-17 17:09  jack_Meng  阅读(356)  评论(0编辑  收藏  举报

导航