プロジェクトでは、正規表現を使用してさまざまな種類の文を区別し、これらの文を処理する関数にマップする実験を行っています。
これらの文処理関数のほとんどは、正規表現のキャプチャ グループによって解析された文自体から引数を取ります。
例: 「私は 2 つの Cookie に対して $20 を支払いました」は、解析ツリー (辞書) の正規表現の 1 つと一致します。この正規表現は、extract $20 をグループ "price" として、2 をグループ "amount" として一致します。現在、正しい Handler 関数にマッピングし、次のように呼び出しています。
foreach(KeyValuePair<Regex, Type> pair in sentenceTypes)
{
Match match = pair.Key.Match(text);
if(match.Success)
{
IHandler handler = handlerFactory.CreateHandler(pair.Value);
output = handler.Handle(match);
}
}
単純なハンドラー クラスの例。
public class NoteCookiePriceHandler
{
public string Handle(Match match)
{
double payment = Convert.ToDouble(match.Result("${payment}"));
int amount = Convert.ToInt32(match.Result("${amount}"));
double price = payment / amount;
return "The price is $" + price;
}
}
Moq を使用していくつかの単体テストをセットアップしようとしていたときに、Match オブジェクトや Regex を実際にモックできないことに気付きました。もっと考えてみると、名前付きグループが正しく解析され、適切なインターフェースなしで Handler クラスに渡されることに依存しているため、一般的に設計に多少の欠陥があるようです。
Match オブジェクトの受け渡しには問題があるように思われるため、マッピングされたハンドラ関数/クラスにパラメータを正しく渡す際に使用する、より効果的な設計に関する提案を探しています。
それができない場合は、RegexまたはMatchを効果的にモックする方法を見つけ出すための助けがあれば幸いです.少なくとも私の短期的な問題を解決するのに役立ちます. どちらもデフォルトのコンストラクターがないため、Moq でそれらのオブジェクトを作成するのに苦労しています。
編集:(Moqできない)一致オブジェクト自体ではなく、一致グループに文字列の辞書を渡すことで、少なくともモックの問題を解決することになりました。私はこの解決策に特に満足しているわけではないので、推奨事項を引き続き歓迎します。
foreach(KeyValuePair<Regex, Type> pair in sentenceTypes)
{
match = pair.Key.Match(text);
if(match.Success)
{
IHandler handler= handlerFactory.CreateHandler(pair.Value);
foreach (string groupName in pair.Key.GetGroupNames())
{
matchGroups.Add(groupName, match.Groups[groupName].Value);
}
interpretation = handler.Handle(matchGroups);