2012-06-05 38 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。事實上,我從來沒有使用動態類型之前:) –