3

nUnit / nMock /ユニットテストの初心者の質問のビット:

このクラスをユニットテストしようとしています。

「getCurrencyRates」から返される値を知りたいので、そのデータに基づいてテストを作成できるように、モックを作成しました。

そこで、このオブジェクトのモックを作成しました(返された為替レートを知るためだけに)。

...しかし今、私はこのクラスの他のメソッドのいくつかも呼び出したいと思います。

するべきか:

a)どういうわけかモックオブジェクトから実際のメソッドを呼び出します(それが可能かどうかさえわかりません)b)Webサービス呼び出しのみがそれ自体のオブジェクトに含まれるようにリファクタリングし、そのモックを作成しますc)何か他のもの?

public class CurrencyConversion : ICurrencyConversion
{
    public decimal convertCurrency(string fromCurrency, string toCurrency, decimal amount)
    {

        CurrencyRateResponse rates = getCurrencyRates();
        var fromRate = getRate(rates, fromCurrency);
        var toRate = getRate(rates, toCurrency);

        decimal toCurrencyAmount = toRate / fromRate * amount;

        return toCurrencyAmount;
    }


    public int addNumbers(int i, int j)
    {
        return i + j;

    }

    public decimal getRate(CurrencyRateResponse rates, string fromCurrency)
    {

        if (rates.rates.ContainsKey(fromCurrency))
        {
            return rates.rates[fromCurrency];
        }
        else
        {
            return 0;
        }
    }
    public CurrencyRateResponse getCurrencyRates()
    {
        HttpWebRequest webRequest = GetWebRequest("http://openexchangeerates.org/latest.json");

        HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
        string jsonResponse = string.Empty;
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            jsonResponse = sr.ReadToEnd();
        }

        var serializer = new JavaScriptSerializer();
        CurrencyRateResponse rateResponse = serializer.Deserialize<CurrencyRateResponse>(jsonResponse);

        return rateResponse;

    }
    public HttpWebRequest GetWebRequest(string formattedUri)
    {
        // Create the request’s URI.
        Uri serviceUri = new Uri(formattedUri, UriKind.Absolute);

        // Return the HttpWebRequest.
        return (HttpWebRequest)System.Net.WebRequest.Create(serviceUri);
    }
}
4

2 に答える 2

3

現時点CurrencyConverterでは、2つのことを行っています。通貨を変換すること(これは良いことです)と、外部サービスを呼び出してデータをフェッチすること(これは悪いことです)です。あなたはあなたのクラスが単一の、簡単に定義できる責任を持っていることを望みます。そうすれば、コードははるかにクリーンで管理しやすくなり、このコンテキストで重要なことは、よりテストしやすくなります。

getCurrencyRatesデータ提供メソッド( )を外部サービス(クラス)にリファクタリングし、コンバーターオブジェクトに注入します(たとえば、コンストラクター注入を介して)。

また、なぜNMocksなのですか?もはや積極的に開発されていません(最後の更新は4〜6年前のようです) 。FakeItEasyMoqなどの最新のフレームワークほど使いやすいものではないと思われるかもしれません。

于 2012-02-15T08:34:03.570 に答える
2

あなたはb)のようなことをしたいと思うでしょう。オブジェクトをテストしている場合は、オブジェクト自体をモックするのではなく、その依存関係をモックする必要があります。

モックアウトしたい依存関係は、Webサービスへの呼び出しです。実際のWebサービス呼び出しをnunitテストに入れると、単体テストとは何かに違反するだけでなく、実装するのも悪夢になります。

webserice呼び出しを含む部分のインターフェースを作成します

ICurrencyRateService 
{
     CurrencyRateResponse GetCurrencyRates()
}

次に、これを実装するオブジェクトにすべてのwebserviceyコードを取得します。

これにより、ConvertCurrencyをテストできるようになります。また、オブジェクト間の関心の分離が改善され、Webサービスを呼び出す1つのオブジェクトと、計算を行う1つのオブジェクトがあることも意味します。

于 2012-02-15T08:21:17.983 に答える