35

我正在尝试测试一些依赖于 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 也不起作用,因为构造函数是 RouteData(RouteBase,IRouteHandler)。

这里重要的类是抽象类 RouteBase,它有方法 GetRouteData(HttpContextBase),它返回一个 RouteData 的实例,我试图伪造的类。带我兜兜转转!

对此的任何帮助都将受到欢迎。

4

2 回答 2

65

RouteData 还有一个不带参数的构造函数。只需创建一个并向其添加您想要的值。当您可以创建一个时,无需模拟它。

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

 var controllerContext = new ControllerContext(httpContextMock.Object, routeData, controllerMock.Object);
于 2009-06-12T12:01:23.260 回答
1

我对结合模拟对象的 TDD 非常陌生,但我早期从一位同事那里学到的教训是不要模拟你不拥有的类型。因此,不要试图模拟 RouteData。这个想法最初是由Joe Walnes构思的(虽然我找不到他说的地方)。

于 2009-06-12T12:23:03.117 回答