1. ホーム
  2. c#

[解決済み] Moq - オーバーライド不可能なメンバをセットアップ/検証式で使用することはできません。

2023-06-10 09:09:32

質問

Moqを使い始めたばかりです。をモックしています。 PagingOptions クラスをモックしています。以下は、クラスがどのように見えるかです。

public class PagingOptions
    {
        [Range(1, 99999, ErrorMessage = "Offset must be greater than 0.")]
        public int? Offset { get; set; }

        [Range(1, 100, ErrorMessage = "Limit must be greater than 0 and less than 100.")]
        public int? Limit { get; set; }

        public PagingOptions Replace(PagingOptions newer)
        {
            return new PagingOptions
            {
                Offset = newer.Offset ?? Offset,
                Limit = newer.Limit ?? Limit
            };
        }
    }

以下は、私のモック版のクラスです。

var mockPagingOptions = new Mock<PagingOptions>();
            mockPagingOptions.Setup(po => po.Limit).Returns(25);
            mockPagingOptions.Setup(po => po.Offset).Returns(0);

プロパティ値を設定する際に、以下のようなエラーが発生します。私が何か間違ったものを作っているのでしょうか。コンクリートクラスはモックできないようですが?モックできるのはインターフェイスだけですか? よろしくお願いします。

ありがとうございます。 Abdul

どのように解決するのですか?

Moqはモックされた型の実装を作成します。型がインターフェースの場合、そのインターフェースを実装したクラスを作成します。クラスであれば、継承クラスを作成し、その継承クラスのメンバが基底クラスを呼び出します。しかし、そのためにはメンバをオーバーライドする必要があります。もしクラスにオーバーライドできないメンバー(仮想、抽象でない)がある場合、Moqはそれらをオーバーライドして独自の動作を追加することができません。

この場合、モックする必要はありません。 PagingOptions を使うのは簡単だからです。そのかわり、このように

var mockPagingOptions = new Mock<PagingOptions>();
mockPagingOptions.Setup(po => po.Limit).Returns(25);
mockPagingOptions.Setup(po => po.Offset).Returns(0);

これを実行します。

var pagingOptions = new PagingOptions { Limit = 25, Offset = 0 };

モックを作成するかどうかは、どのように判断すればよいのでしょうか。一般的には、具体的な実行時実装をテストに含めたくない場合にモックを使用します。同時に2つのクラスをテストするのではなく、1つのクラスをテストしたいのです。

しかし、この場合 PagingOptions は単にデータを保持するクラスです。これをモック化する意味はありません。本物を使う方が簡単です。