单元测试返回匿名类型的Response RedirectToRoute

时间:2015-02-16 19:59:29

标签: c# unit-testing tdd rhino-mocks anonymous-types

我正在使用HttpResponseBase对象测试AspNet MVC应用程序中的HttpModule,如Kazi Rashid's blog

所示

在我的测试代码中,我有:

context.Response.RedirectToRoute(new { Controller = "C1", Action = "A1" });

在我的单元测试中(在单独的测试项目中使用RhinoMocks),我可以使用以下方法获取传递给此方法的实际参数:

var actual = this.ResponseMock.GetArgumentsForCallsMadeOn(r => r.RedirectToRoute(new { Controller = "dummy", Action = "dummy" }),
            options => options.IgnoreArguments())[0][0];

我可以在测试中创建我期望的参数:

var expected = new {Controller = "C1", Action = "A1" };

当我进行这项测试时,一切看起来都很有希望。如果我把两个"实际"和"预期"在Watch窗口中,我可以看到它们的值看起来相同,并且它们的匿名类型看起来也相同。

但是,当涉及到Assert时,Visual Studio只能看不到Actual上的属性,所以我实际上无法输入我的Assert。如果我键入以下内容:

actual.Controller =

Visual Studio只是说:

  

无法解析符号' Controller'

我已尝试过推荐用于转换为匿名类型的解决方案(例如cast-to-anonymous-type,但这只会引发以下异常:

  

{&#34; [A]&LT;&GT; f__AnonymousType0 2[System.String,System.String] cannot be cast to [B]<>f__AnonymousType0 2 [System.String,System.String]。类型A源自&#39; ^ My Assembly Under Test ^,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;在上下文中&#39;默认&#39;在位置&#39; ^ MyAssemblyUnderTest.dll ^&#39;。类型B源自&#39; ^ My Test Assembly ^,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;在上下文中&#39;默认&#39;在位置&#39; \ ^ MyTestAssembly.dll ^&#39;。&#34;}

我尝试使用Reflection来复制&#39;实际&#39;一个新的匿名类型,但也失败了。只是希望我知道我的Watch窗口是如何做到的......

所以,我追求的是:

  • 理想情况下,在我的实际情况下执行断言的首选方式是&#39;表明它的属性是预期的
  • 或者,一种投射我的实际&#39;我能读到的东西。

提前致谢

格里夫

1 个答案:

答案 0 :(得分:1)

最后解决了......答案是在stackoverflow(还有哪里?)C# ‘dynamic’ cannot access properties from anonymous types declared in another assembly

总结:

正在测试的类(HttpModule Assembly)

context.Response.RedirectToRoute(new { Controller = "C1", Action = "A1" });

测试类(HttpModuleTest Assembly)

var actual = this.ResponseMock
    .GetArgumentsForCallsMadeOn(r => 
        r.RedirectToRoute(new { Controller = "dummy", Action = "dummy" }),
            options => options.IgnoreArguments())[0][0];

var controllerProperty = properties.Find("Controller", false);
var actionProperty = properties.Find("Action", false);

var controllerProperty = properties.Find("Controller", false);
var actionProperty = properties.Find("Action", false);

string controllerValue = controllerProperty.GetValue(actual).ToString();
string actionValue = actionProperty.GetValue(actual).ToString();

然后你可以执行Assert。