最小起订量将动态类型作为对象问题返回

本文关键字:对象 问题 返回 类型 动态 | 更新日期: 2023-09-27 18:36:21

如果

有人问过这个问题,请道歉,但我在任何地方都找不到答案。

我的问题是在使用 MOQ 模拟返回方法时,该方法返回动态类型。 我正在使用使用动态时间的第三方库。 最小起订量似乎将动态类型转换为对象。

Mock<IFacebookHelper> mockFbHelp = new Mock<IFacebookHelper>();
mockFbHelp.Setup(x => x.Get("me")).Returns(new { email = "test@test.com", 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 返回了一种动态类型的对象,需要将其转换为某些东西。

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

编辑

实际上,我不认为这是最小起订量问题,因为我创建了自己的模拟课程,但仍然遇到同样的问题。 我是动态类型的新手,所以不确定发生了什么。

编辑 2 - 部分已回答..毕竟问题与最小起订量无关

实际上,问题似乎是由于在不同的程序集中创建动态类型造成的。 虽然我使用 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" };
        }
    }
}

有3个项目由命名空间MyLib,Warrior.WebUI和Warrior.Tests表示。
因为它是测试失败并出现错误。"对象"不包含"动态属性"的定义发生在 RetTest() 上

但是,如果我简单地将DynTestProxy类移动到Warrior.WebUI项目中,一切正常。 我猜在不同的程序集或其他东西之间发送动态类型时会出现问题。

最小起订量将动态类型作为对象问题返回

我做了一个快速测试:

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 = "test@test.com", 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 属性。有关更多信息,请参阅此处。这个问题对你来说也可能很有趣。