单元测试的艺术 -- 系列文章(附测试代码)
出处 :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; } } }
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); } } } } }
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; } } }
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); } } }
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")); } } }
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); } } }
说明:其中部分使用了Microsoft Fakes写的测试代码,请参考:使用 Microsoft Fakes 进行单元测试
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/13153542.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!