web-dev-qa-db-ja.com

MVCアプリケーション用のSystem.Web.RoutingのRouteDataクラスのモック

ControllerContext.RouteDataのValuesプロパティに依存するいくつかのアプリケーションロジックをテストしようとしています。

これまでのところ私は持っています

// Arrange
var httpContextMock = new Mock<HttpContextBase>(MockBehavior.Loose);
var controllerMock = new Mock<ControllerBase>(MockBehavior.Loose);
var routeDataMock = new Mock<RouteData>();

var wantedRouteValues = new Dictionary<string, string>();
wantedRouteValues.Add("key1", "value1");
var routeValues = new RouteValueDictionary(wantedRouteValues);

routeDataMock.SetupGet(r => r.Values).Returns(routeValues);  <=== Fails here

var controllerContext = new ControllerContext(httpContextMock.Object, routeDataMock.Object, controllerMock.Object);

単体テストは次のように失敗します:System.ArgumentException:オーバーライド不可能なメンバーのセットアップが無効です:r => r.Values

コンストラクターがRouteData(RouteBase、IRouteHandler)であるため、偽のRouteDataの作成も機能しません。

ここで重要なクラスは、私が偽造しようとしているクラスであるRouteDataのインスタンスを返すGetRouteData(HttpContextBase)メソッドを持つ抽象クラスRouteBaseです。輪になって連れて行ってくれ!

これに関するどんな助けでも大歓迎です。

35
Magpie

RouteDataには 引数を取らないコンストラクター もあります。作成して、必要な値を追加するだけです。作成できるときにモックする必要はありません。

 var routeData = new RouteData();
 routeData.Values.Add( "key1", "value1" );

 var controllerContext = new ControllerContext(httpContextMock.Object, routeData, controllerMock.Object);
64
tvanfosson

私はモックオブジェクトと組み合わせたTDDに非常に慣れていませんが、同僚から早い段階で学んだ教訓は、所有していないタイプをモックすることではありませんでした。したがって、RouteDataをモックしようとしないでください。このアイデアはもともと Joe Walnes によって考案されました(彼がどこで言ったかはわかりませんが)。

1
John Berberich