我的代碼由以下組件組成:
1 - IMyService:定義將實作它的類的屬性/方法的介面。
2 - MyService : IMyService 的具體實作。
public interface IMyService
{
Task<MyResult> CreateAsync(string id, string json);
}
internal class MyService : IMyService
{
private readonly ExternalService _externalService;
public class MyService(ExternalService externalService)
{
this._externalService = externalService;
}
public async Task<MyResult> CreateAsync(string id, string json)
{
ServiceResult serviceResult = await this._externalService.RunAsync(id, json);
return new MyResult(serviceResult);
}
}
MyService類依賴于名為ExternalService的第三方庫/SDK/包并實作方法CreateAsync。
CreateAsync 方法接受 2 個輸入引數,在 ExternalService 上呼叫RunAsync方法,接收結果并從結果創建我自己的類。
問題1)
我將如何處理 MyService 類中的單元測驗 CreateAsync 方法?因為它不包含邏輯,所以為它撰寫單元測驗有什么價值嗎?
問題2)
ExternalService 有它自己的例外,它可以在執行 RunAsync 方法時拋出 - 我應該捕獲 RunAsync 拋出的例外(將 try/catch 包裹起來)并將它們轉換為我自己的例外嗎?例如 - ExternalServiceException => MyServiceException。
uj5u.com熱心網友回復:
用Moq和Autofixture模擬它。我不知道您打算使用什么單元測驗框架。所以我會以 Xunit 為例。如果是對外部服務的呼叫,您只對測驗它可以回傳的內容感興趣。
首先創建一個 autofixture 類。這是我們的測驗用例所必需的屬性。更多資訊在這里
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture()
.Customize(new AutoMoqCustomization()))
{
}
}
[Theory]
[AutoMoqData]
public async Task Validate_Service_ReturnResult([Frozen]Mock<IMyService> someService, ServiceResult mockResult, SomeClass sut){
//Set up interface to return what you want.
//In this case it returns mockResult always,
//but you can edit the properties of this to be whatever best fits your test case.
someService.Setup(x => x.CreateAsync(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(mockResult);
var result = await someService.Object.CreateAsync("ree", "skee");
//The class we are actually testing
var res =sut.DoSomething("someId", "someJson")
Assert.NotNull(res);
}
[Frozen] 屬性確保被模擬的 someService 的行為在您的所有代碼中都是相同的。
做這一切比為每個測驗用例“偽造”你的界面要好得多。想象一下,您希望 CreateAsync 回傳不同的 httpcode,例如 404、200 或 500。為每種情況創建一個新的介面實作很有趣。使用 autofixture,您只需在測驗用例的開頭進行設定。
我們要在其上運行測驗的類
public class SomeClass{
IMyService someService;
public SomeClass(IMyservice someService){
this.someService = someService
}
public async Task<string> DoSomething(string id, string json){
var res = await this.someService.CreateAsync(id, json);
if(res.HttpStatusCode == 200){
//then do bla bla bla
...
}
}
問題1:是的。對您的服務進行單元測驗絕對值得。您需要查看您的代碼是否處理負面結果。如果這是一個因為沒有正確處理結果而崩潰的服務,那就太糟糕了。例如,如果您期望來自服務的物件但收到 null。然后不久你就會有一個空參考例外和一個崩潰的服務。
問題2:沒關系。無論哪種方式,都應記錄例外。如果您想要記錄一些重要的事情,那么您可以輕松地查詢它,例如。Http代碼。那么請做。這取決于兩件事。第一:你能處理例外嗎?第二:您是否將例外記錄到某個中央資料庫?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/530685.html
標籤:C#单元测试
