前言

接續完成我們 API 的單元測試,前面示範過的部分就不會再重複敘述,有比較特別的地方會特別提醒,那就開始吧。

本文

GetAccount(取得單筆帳號資訊)

1、輸入的 Account 不可為空。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "GetAccount")]
        public void GetAccount_Account為空_應回傳Exception()
        {
            //arrange
            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.GetAccount("");

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("Account 不可為空 !");
        }

2、若查詢的 Account 有資料應回傳正確資訊。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "GetAccount")]
        public void GetAccount_Account有資料_應回傳正確資訊()
        {
            //arrange
            var data = new AccountDataModel()
            { 
                Account = "test123",
                CreateDate = DateTime.Now,
                ModifyDate = DateTime.Now,
                Email = "test123@gmail.com",
                ModifyUser = "sys",
                Phone = "0918777888"
            };
            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test123").Returns(data);

            var expect = new AccountDto()
            {
                Account = "test123",
                CreateDate = DateTime.Now.ToString("yyyy/MM/dd"),
                ModifyDate = DateTime.Now.ToString("yyyy/MM/dd"),
                Email = "test123@gmail.com",
                ModifyUser = "sys",
                Phone = "091877****"
            };
            //act
            var actual = sut.GetAccount("test123");

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

3、若查詢的 Account 無資料應回傳空值。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "GetAccount")]
        public void GetAccount_Account無資料_應回傳空值()
        {
            //arrange
            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test123").ReturnsForAnyArgs(x => null);

            //act
            var actual = sut.GetAccount("test123");

            //assert
            actual.Should().BeNull();
        }

結果:

這就抓到了一個錯誤,應該為 Null 的地方沒有正確轉型,我們就可以回頭檢查一下程式。

在 AccountDataModel 的地方,我們使用了 DateTime 型別。

因為有可能會是 Null 的情況所以我們改變一下做法。

    public class AccountDataModel
    {
        /// <summary>
        /// 帳號
        /// </summary>
        public string Account { get; set; }

        /// <summary>
        /// 電話
        /// </summary>
        public string Phone { get; set; }

        /// <summary>
        /// 信箱
        /// </summary>
        public string Email { get; set; }

        /// <summary>
        /// 建立日期
        /// </summary>
        public DateTime? CreateDate { get; set; }

        /// <summary>
        /// 異動日期
        /// </summary>
        public DateTime? ModifyDate { get; set; }

        /// <summary>
        /// 異動人員
        /// </summary>
        public string ModifyUser { get; set; }
    }

接著看錯誤清單,我們會需要修改使用到的地方。
第一個是 Service Mapping 的地方,改成這樣。

    public ServiceProfile()
        {
            this.CreateMap<AccountDataModel, AccountDto>()
                .ForMember(x => x.CreateDate, y => y.MapFrom(z => z.CreateDate.HasValue ? z.CreateDate.Value.ToString("yyyy/MM/dd") : null))
                .ForMember(x => x.ModifyDate, y => y.MapFrom(z => z.ModifyDate.HasValue ? z.ModifyDate.Value.ToString("yyyy/MM/dd") : null));

            this.CreateMap<AccountInfoModel, AccountCondition>();
        }

第二個是 GetAccountList 這個方法使用的地方,改成這樣。

    public IEnumerable<AccountDto> GetAccountList()
        {
            var data = this._accountRepository.GetAccountList();
            var result = data.Select(x => new AccountDto
            {
                Phone = ConvertPhoneNumber(x.Phone),
                Account = x.Account,
                CreateDate = x.CreateDate.HasValue ? x.CreateDate.Value.ToString("yyyy/MM/dd") : null,
                Email = x.Email,
                ModifyDate = x.ModifyDate.HasValue ? x.ModifyDate.Value.ToString("yyyy/MM/dd") : null,
                ModifyUser = x.ModifyUser
            });

            return result;
        }

接著回頭執行我們剛剛的測試。

回頭檢查 Service 方法,少了一個驗證,改成。

        /// <summary>
        /// 取得單筆帳號資訊
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public AccountDto GetAccount(string account)
        {
            if (string.IsNullOrWhiteSpace(account))
            {
                throw new Exception("Account 不可為空 !");
            }

            var data = this._accountRepository.GetAccount(account);
            var result = this._mapper.Map<AccountDto>(data);
            if (result != null)
            {
                result.Phone = ConvertPhoneNumber(result.Phone);
            }
            return result;
        }

重新執行測試。

成功,有沒有開始體會單元測試的好處了啊?

ConvertPhoneNumber(轉換電話號碼)

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ConvertPhoneNumber")]
        public void ConvertPhoneNumber_輸入空字串_應直接回傳空字串()
        {
            //assert
            var sut = this.GetSystemUnderTest();
            var method = sut.GetType().GetMethod("ConvertPhoneNumber", BindingFlags.Instance | BindingFlags.NonPublic);

            //act
            var actual = method.Invoke(sut, new[] { string.Empty });

            //arrange
            actual.Should().Be(string.Empty);
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ConvertPhoneNumber")]
        public void ConvertPhoneNumber_輸入電話號碼_應回傳轉換後結果()
        {
            //assert
            var sut = this.GetSystemUnderTest();
            var method = sut.GetType().GetMethod("ConvertPhoneNumber", BindingFlags.Instance | BindingFlags.NonPublic);
            var expect = "091877****";

            //act
            var actual = method.Invoke(sut, new[] { "0918777888" });

            //arrange
            actual.Should().Be(expect);
        }

GetAccountList(取得帳號列表)

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "GetAccountList")]
        public void GetAccountList_無資料_應回傳空值()
        {
            //arrange
            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccountList().ReturnsForAnyArgs(x => null);

            //act
            var actual = sut.GetAccountList();

            //assert
            actual.Should().BeNull();
        }

修改 Service 方法。

         /// <summary>
        /// 取得帳號列表
        /// </summary>
        /// <returns></returns>
        public IEnumerable<AccountDto> GetAccountList()
        {
            IEnumerable<AccountDto> result;
            var data = this._accountRepository.GetAccountList();
            if (data != null && 
                data.Any())
            {
                result = data.Select(x => new AccountDto
                {
                    Phone = ConvertPhoneNumber(x?.Phone),
                    Account = x?.Account,
                    CreateDate = x.CreateDate.HasValue ? x.CreateDate.Value.ToString("yyyy/MM/dd") : null,
                    Email = x?.Email,
                    ModifyDate = x.ModifyDate.HasValue ? x.ModifyDate.Value.ToString("yyyy/MM/dd") : null,
                    ModifyUser = x?.ModifyUser
                });
            }
            else
            {
                result = null;
            }
            
            return result;
        }

回頭執行測試。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "GetAccountList")]
        public void GetAccountList_有資料_應回傳正確結果()
        {
            //arrange
            var data = new List<AccountDataModel>
            { 
                new AccountDataModel
                {
                    Account = "test123",
                    CreateDate = DateTime.Now,
                    ModifyDate = DateTime.Now,
                    Email = "test123@gmail.com",
                    ModifyUser = "sys",
                    Phone = "0918777888"
                }
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccountList().Returns(data);

            var expect = new List<AccountDto>
            { 
                new AccountDto
                {
                    Account = "test123",
                    CreateDate = DateTime.Now.ToString("yyyy/MM/dd"),
                    ModifyDate = DateTime.Now.ToString("yyyy/MM/dd"),
                    Email = "test123@gmail.com",
                    ModifyUser = "sys",
                    Phone = "091877****"
                }
            };
            //act
            var actual = sut.GetAccountList();

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

RemoveAccount(刪除帳號)

1、有三個必填欄位需要確認。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_傳入的Account為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            { 
                Account = "",
                Email = "test22@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.RemoveAccount(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_傳入的Email為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.RemoveAccount(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_傳入的Phone為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test22@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = ""
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.RemoveAccount(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

2、查無帳號應回傳錯誤訊息。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_查無帳號_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test111122",
                Email = "test22@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var expect = new ResultDto
            {
                Success = false,
                Message = "請確認要刪除的帳號!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test111122").ReturnsForAnyArgs(x => null);

            //act
            var actual = sut.RemoveAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

3、確認資料是否一致。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_輸入Email與資料不一致_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test111122",
                Email = "test22@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var checkInfo = new AccountDataModel
            {
                Account = "test111122",
                CreateDate = DateTime.Now,
                ModifyDate = DateTime.Now,
                Email = "test123@gmail.com",
                ModifyUser = "sys",
                Phone = "0988123456"
            };

            var expect = new ResultDto
            {
                Success = false,
                Message = "請確認輸入的EMail是否與註冊時一致!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test111122").Returns(checkInfo);

            //act
            var actual = sut.RemoveAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }
        
        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_輸入電話與資料不一致_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test111122",
                Email = "test123@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123412"
            };

            var checkInfo = new AccountDataModel
            {
                Account = "test111122",
                CreateDate = DateTime.Now,
                ModifyDate = DateTime.Now,
                Email = "test123@gmail.com",
                ModifyUser = "sys",
                Phone = "0988123456"
            };

            var expect = new ResultDto
            {
                Success = false,
                Message = "請確認輸入的電話是否與註冊時一致!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test111122").Returns(checkInfo);

            //act
            var actual = sut.RemoveAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

4、刪除結果。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_刪除失敗_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test111122",
                Email = "test123@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var checkInfo = new AccountDataModel
            {
                Account = "test111122",
                CreateDate = DateTime.Now,
                ModifyDate = DateTime.Now,
                Email = "test123@gmail.com",
                ModifyUser = "sys",
                Phone = "0988123456"
            };

            var expect = new ResultDto
            {
                Success = false,
                Message = "刪除失敗"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test111122").Returns(checkInfo);
            this._accountRepository.RemoveAccount("test111122").Returns(false);

            //act
            var actual = sut.RemoveAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "RemoveAccount")]
        public void RemoveAccount_刪除成功_應回傳正確訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test111122",
                Email = "test123@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var checkInfo = new AccountDataModel
            {
                Account = "test111122",
                CreateDate = DateTime.Now,
                ModifyDate = DateTime.Now,
                Email = "test123@gmail.com",
                ModifyUser = "sys",
                Phone = "0988123456"
            };

            var expect = new ResultDto
            {
                Success = true,
                Message = "刪除成功"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test111122").Returns(checkInfo);
            this._accountRepository.RemoveAccount("test111122").Returns(true);

            //act
            var actual = sut.RemoveAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

UpdateAccount(更新帳號資訊)

1、有兩個必填欄位需要確認。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "UpdateAccount")]
        public void UpdateAccount_輸入帳號為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "",
                Email = "test123@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.UpdateAccount(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "UpdateAccount")]
        public void UpdateAccount_輸入密碼為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.UpdateAccount(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

2、找無輸入帳號之密碼資訊。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "UpdateAccount")]
        public void UpdateAccount_找無輸入帳號之密碼資訊_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "請確認要更新的帳號!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccountPassword("test2").Returns("");

            //act
            var actual = sut.UpdateAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

3、輸入帳號之密碼與註冊時不一致。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "UpdateAccount")]
        public void UpdateAccount_輸入之密碼與註冊時不一致_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "請確認輸入的密碼是否與註冊時一致!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccountPassword("test2").Returns("9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWP");

            //act
            var actual = sut.UpdateAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

4、更新結果。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "UpdateAccount")]
        public void UpdateAccount_更新失敗_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "更新失敗"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccountPassword("test2").Returns("9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=");
            this._accountRepository.UpdateAccount(Arg.Any<AccountCondition>()).Returns(false);

            //act
            var actual = sut.UpdateAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }
        
        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "UpdateAccount")]
        public void UpdateAccount_更新成功_應回傳正確訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = true,
                Message = "更新成功"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccountPassword("test2").Returns("9GYVaHLoOg+y+V/HHwKtkzBH3y8XWn14h8ifWPYViLc=");
            this._accountRepository.UpdateAccount(Arg.Any<AccountCondition>()).Returns(true);

            //act
            var actual = sut.UpdateAccount(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

ForgetPassword(忘記密碼)

1、有四個必填欄位需要確認。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_輸入之帳號為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.ForgetPassword(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_輸入之Email為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "",
                Password = "12371324",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.ForgetPassword(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_輸入之密碼為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test2@gmail.com",
                Password = "",
                Phone = "0988123456"
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.ForgetPassword(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_輸入之電話為空_應回傳Exception()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test2@gmail.com",
                Password = "12371324",
                Phone = ""
            };

            var sut = this.GetSystemUnderTest();

            //act
            Action actual = () => sut.ForgetPassword(data);

            //assert
            actual.Should().Throw<Exception>()
                .Which.Message.Contains("請檢查輸入欄位,缺一不可!");
        }

2、找無輸入之帳號資訊。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_找無輸入之帳號資訊_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "請確認輸入之帳號!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test2").ReturnsForAnyArgs(x => null);

            //act
            var actual = sut.ForgetPassword(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

3、確認資料是否一致。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_輸入之Email與註冊不一致_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var returnData = new AccountDataModel()
            {
                Account = "test2",
                Email = "test12345@gmail.com",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "請確認輸入的Email,是否與註冊時一致!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test2").Returns(returnData);

            //act
            var actual = sut.ForgetPassword(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_輸入之電話與註冊不一致_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var returnData = new AccountDataModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Phone = "0988123777"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "請確認輸入的電話,是否與註冊時一致!"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test2").Returns(returnData);

            //act
            var actual = sut.ForgetPassword(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

4、更新結果。

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_更新失敗_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var returnData = new AccountDataModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = false,
                Message = "更新密碼失敗"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test2").Returns(returnData);
            this._accountRepository.ForgetPassword(Arg.Any<AccountCondition>()).Returns(false);

            //act
            var actual = sut.ForgetPassword(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

        [TestMethod]
        [Owner("Sian")]
        [TestCategory("AccountServiceTest")]
        [TestProperty("AccountServiceTest", "ForgetPassword")]
        public void ForgetPassword_更新成功_應回傳錯誤訊息()
        {
            //arrange
            var data = new AccountInfoModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Password = "12371324",
                Phone = "0988123456"
            };

            var returnData = new AccountDataModel()
            {
                Account = "test2",
                Email = "test123@gmail.com",
                Phone = "0988123456"
            };

            var expect = new ResultDto()
            {
                Success = true,
                Message = "更新密碼成功"
            };

            var sut = this.GetSystemUnderTest();
            this._accountRepository.GetAccount("test2").Returns(returnData);
            this._accountRepository.ForgetPassword(Arg.Any<AccountCondition>()).Returns(true);

            //act
            var actual = sut.ForgetPassword(data);

            //assert
            actual.Should().BeEquivalentTo(expect);
        }

測試結果

後記

這樣就補完我們 API 的單元測試了,這次示範也是找了自己先前應該注意到的回傳值錯誤,是不是馬上體現單元測試的重要性,可以及早發現問題,當然因為這是採用事後補上測試的做法,如果是 TDD 的模式,在開發的當下就能發現錯,盡早解決問題。

一樣會把程式放在 Github 有需要的歡迎取用。