我試圖將測試添加到遺留代碼,並且當我開始添加代碼時,我感覺到某些錯誤。根據私有方法測試公共方法的方法
在下面的代碼,public方法RegisterChange呼籲兩個私有方法:
- 獲取對象存儲
- 存儲對象
public class ChangeService {
IRepository repository;
public ChangeService(IRepository repository){
this.repository = repository;
}
public bool RegisterChange(int entityId){
var entity = GetParsedEntity(entityId);
SaveEntity(entity);
return true;
}
private Entity GetParsedEntity(int id) {
var entity = repository.GetEntityById(id);
return new Entity{ Name = entity.Name };
}
private void SaveEntity(Entity entity) {
repository.Save(Entity);
}
}
public class ChangeServiceFact(){
[Fact]
public void When_valid_entity__Should_save_entity(){
var mock = new Mock<IRepository>();
var service = new ChangeService(mock.object);
var result = service.RegisterChange(0);
Assert.True(result);
}
}
所以,當林嘲笑庫,我不得不去檢查私有方法的代碼,以知道哪些操作來模擬。
我用這種方法看到的問題是,因爲代碼不僅測試測試主體(公共方法)而且測試私有方法,因此不清楚應該通過查看測試結果測試主題(公共方法)。
在稍後有人決定修改一個私有方法(如從GetParsedEntity拋出異常)時,測試將繼續正確傳遞,但由於此更改,客戶端代碼可能會失敗。
在這種特殊情況下,我使用C#,XUnit和Moq,但我認爲更通用的測試問題。
當然,測試不會*通過,因爲當您調用'RegisterChange'時會引發異常。如果它有時*會拋出一個異常,那麼由做出更改的人來爲其添加一個測試。它應該符合公共方法的*記錄*(ahem)行爲。 –
@JonSkeet,讓我們說GetParsedInt的變化不是一個突破的,而是一個新的功能,在這種情況下,舊的測試不知道這一點。我知道一個新的測試會拿起新的功能測試。所以,我的問題是「這是正常的方法嗎?」 (只是爲了說出它的名字)。謝謝。 – andymaster01
這樣說:'GetParsedEntity'的代碼是否內聯到public方法中不應該影響測試。這是一個實現細節。所以,如果你沒有破壞任何東西,只需添加一個單獨測試的新功能,你最關心的是什麼?對我來說似乎很合理。 –