2012-06-05 41 views
3

pologise如果这个问题已被问到,但我无法在任何地方找到答案。MOQ返回动态类型作为对象问题

我的问题是嘲笑使用MOQ返回方法返回动态类型的返回方法。我正在使用使用动态时间的第三部分库。 MOQ似乎将动态类型作为对象。

Mock<IFacebookHelper> mockFbHelp = new Mock<IFacebookHelper>(); 
mockFbHelp.Setup(x => x.Get("me")).Returns(new { email = "[email protected]", id="9999" }); 

方法在嘲笑的帮手。

public dynamic Get(string p) 
{ 
    var client = new FacebookClient(AccessToken); 
    return client.Get("me"); 
} 

来自控制器的代码使用模拟结果。

_facebookHelper.AccessToken = accessToken; 
dynamic result = _facebookHelper.Get("me"); 
int facebookId = int.Parse(result.id); //This errors as id doesn't exist. 

基本上MOQ返回动态类型的对象,要求铸造的东西。

有谁知道如何解决这个问题?我假设这可能是因为MOQ没有在.NET 4中编码,因此不支持动态类型?

编辑

其实我不认为这是一个最小起订量问题,我创建了自己的模拟类,仍然有同样的问题。虽然我不清楚发生了什么,但我对动态类型很陌生。

编辑2 - 部分回答..问题无关MOQ所有

后其实这个问题似乎是由于动态类型在不同的组件被创建。虽然我用JObject类型了解了最初的问题,但我仍然想知道这一点。

namespace MyLib.Tools 
{ 
    public interface IDynTest 
    { 
     dynamic GetData(); 
    } 
} 
namespace MyLib.Tools 
{ 
    public class DynTest : Effect.Tools.IDynTest 
    { 
     public dynamic GetData() { 
      return new { DynamicProperty = "hello" }; 
     } 
    } 
} 
namespace Warrior.WebUI.Infrastructure 
{ 
    public class UseDynTest 
    { 
     private readonly IDynTest dynTest; 

     public UseDynTest(IDynTest dynTest) 
     { 
      this.dynTest = dynTest; 
     } 

     public string RetTest() 
     { 
      return dynTest.GetData().DynamicProperty; 
     } 
    } 
} 
namespace Warrior.Tests 
{ 
    [TestClass] 
    public class TestDynTest 
    { 
     [TestMethod] 
     public void TestMethod1() 
     { 
      //Mock<IDynTest> mockDynTest = new Mock<IDynTest>(); 
      //mockDynTest.Setup(x => x.GetData()).Returns(new { DynamicProperty = "From Unit Test" }); 

      DynTestProxy dynTestProxy = new DynTestProxy(); 

      UseDynTest useTest = new UseDynTest(dynTestProxy); 

      string results = useTest.RetTest(); 

      Assert.AreEqual("From Unit Test", results); 
     } 
    } 
} 
namespace Warrior.Tests 
{ 
    public class DynTestProxy:IDynTest 
    { 
     public dynamic GetData() 
     { 
      return (dynamic) new { DynamicProperty = "From Unit Test" }; 
     } 
    } 
} 

存在由命名空间MyLib中,Warrior.WebUI和Warrior.Tests表示3项目。
由于它是测试失败,并显示错误.. “对象”中不包含关于“DynamicProperty” 发生上RetTest()

然而的定义,如果我只需移动DynTestProxy类进Warrior.WebUI项目一切工作正常。我猜在发送不同程序集的动态类型时会出现问题。

+0

动态只是一个C#关键字,没有类型'动态'。如果你使用任何对象,通过一个动态的本地名称为'id'的属性/字段,它应该可以工作。 – Bond

回答

7

我做了一个快速测试:

namespace ConsoleApplication5 
{ 
    public interface IFacebookHelper { dynamic Get(string p); } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Mock<IFacebookHelper> mockFbHelp = new Mock<IFacebookHelper>(); 
      mockFbHelp.Setup(x => x.Get("me")).Returns(new { email = "[email protected]", id = "9999" }); 

      dynamic result = mockFbHelp.Object.Get("me"); 
      int facebookId = int.Parse(result.id); 
      string email = result.email; 
     } 
    } 
} 

这是工作的罚款。我在这里没有看到问题。

你确定你没有混合一些东西吗?

看看这个方法,你贴:

public dynamic Get(string p) 
{ 
    var client = new FacebookClient(AccessToken); 
    return client.Get("me"); 
} 

也许应该是:

... 
return client.Get(p); 
... 

_facebookHelper真正使用Mock对象?在测试过程中,它应该是IFacebookHelperProxy或类似的东西。

编辑:

的问题是你的企图暴露跨越程序集边界匿名类型,因为你只能在你创建它们的组件使用匿名类型。

所以不是

public class DynTestProxy:IDynTest 
{ 
    public dynamic GetData() 
    { 
     return (dynamic) new { DynamicProperty = "From Unit Test" }; 
    } 
} 

你应该使用一个ExpandoObject

public class DynTestProxy:IDynTest 
{ 
    public dynamic GetData() 
    { 
     dynamic r = new ExpandoObject(); 
     r.DynamicProperty = "From Unit Test"; 
     return r; 
    } 
} 

或使用InternalsVisibleTo属性。有关更多信息,请参阅here。另外this的问题可能会对你有用。

+0

是的,它应该返回client.Get(p)但这不是我得到的问题。我得到的问题似乎是由于最低起订量。我redid很多这个,并创建了我自己的Facebook连接器,它返回一个JObject类型,而且这工作正常。 –

+0

奇怪的是,正如你在我发布的例子中看到的那样,* Moq *和* dynamic *不应该有任何问题。 – sloth

+0

我刚刚编辑了我的文章一点。对于动态类型和不同的程序集来说,它不是最简单的MOQ。无论如何,我通常会对这类事情使用强大的转换类型。我遇到这个问题的唯一原因是由于返回动态类型的Facebook Nuget。事实上,我从来没有使用动态类型之前:) –