これで髪を抜いています。Microsoft Molesで部分スタブを作成して使用する簡単で明確な例を調べましたが、見つかりません。何かが足りないか、コードの設計が不十分なのかもしれませんが、これを機能させることができないようです。
これが私のクラスです(簡略化):
public class AccountService : IAccountService {
private readonly webServiceProxy IExternalWebServiceProxy;
public AccountService(IExternalWebServiceProxy webServiceProxy) {
this.webServiceProxy = webServiceProxy;
}
public List<AccountModel> GetAccounts(string customerId) {
var returnList = new List<AccountModel>();
var xmlResponse = webServiceProxy.GetAllCustomerAccounts(customerId);
var accountNodes = xmlResponse.SelectNodes("//AccountNodes");
if (accountNodes != null)
{
foreach (XmlNode node in accountNodes)
{
var account = this.MapAccountFromXml(node);
if (!string.IsNullOrEmpty(account.AccountNumber))
{
returnList.Add(account);
}
}
}
return returnList;
}
public AccountModel MapAccountFromXml(XmlNode node) {
if (!IsValidAccount(node) {
return null;
}
// This performs a lot of XML manipulation getting nodes based on attributes
// and mapping them to the various properties of the AccountModel. It's messy
// and I didn't want it inline with the other code.
return populatedAccountModel;
{
public bool IsValidAccount(XmlNode node)
{
var taxSelectValue = node.SelectSingleNode("//FORMAT/Field[@taxSelect='1']").First().Value;
var accountStatus = // similar to first line in that it gets a single node using a specific XPath
var maturityDate = // similar to first line in that it gets a single node using a specific XPath
var maturityValue = // similar to first line in that it gets a single node using a specific XPath
return taxSelectValue != string.Empty && taxSelectValue != "0" && (accountStatusValue != "CL" || (maturityDate.Year >= DateTime.Now.AddYears(-1).Year));
}
}
私がやりたいのは、GetAccounts()メソッドをテストすることです。IExternalWebServiceProxy呼び出しをスタブして、偽のXMLを返すことはできますが、GetAccounts()メソッドがMapAccountFromXml()を呼び出し、次にIsValidAccount()を呼び出すため、サービスで内部呼び出しが発生しています。
おそらく解決策は、長くて複雑なMapAccountFromXml()およびIsValidAccount()コードを分割して、GetAccount()呼び出しにインラインで配置することを心配することではありませんが、コードを読みやすくするために、それらを分割したままにしておきます。
Molesアセンブリを作成しましたが、このようなクラスのスタブバージョンを作成できることを知っています
var stubWebService = SIExternalWebServiceProxy {
GetAllCustomerAccounts = delegate {
return SomeHelper.GetFakeXmlDocument();
}
}
var stubAccountService = new SAccountService() { callsBase = true; }
私の問題は、MapAccountFromXmlとIsValidAccountへの内部呼び出しをオーバーライドする方法がわからないことです。また、単体テストでこれらのメソッドをテストしたくないので、テスト用にGetAccountsを分離したいと思います。部分的なスタブでオーバーライドするには仮想である必要があるメソッドをどこかで読みましたが、テストするメソッドのベースを呼び出しているときに、いくつかのメソッドをオーバーライドするスタブを作成する方法を示すものは見つかりませんでした。