如何从Silverlight 5单元测试异步方法

时间:2013-10-22 12:46:36

标签: c# silverlight unit-testing asynchronous dynamics-crm-2011

编辑:上下文:我编写了一个Silverlight应用程序,通过Soap服务访问Dynamics CRM 2011。我实现了这样做的服务。我现在想为这项服务编写单元测试。

我想为以下方法编写单元测试:

public async Task<List<string>> GetAttributeNamesOfEntity(string entityName)
    {
        // build request
        OrganizationRequest request = new OrganizationRequest
        {
            RequestName = "RetrieveEntity",
            Parameters = new ParameterCollection
                {
                    new XrmSoap.KeyValuePair<string, object>()
                        {
                            Key = "EntityFilters",
                            Value = EntityFilters.Attributes
                        },
                    new XrmSoap.KeyValuePair<string, object>()
                        {
                            Key = "RetrieveAsIfPublished",
                            Value = true
                        },
                    new XrmSoap.KeyValuePair<string, object>()
                        {
                            Key = "LogicalName",
                            Value = "avobase_tradeorder"
                        },
                    new XrmSoap.KeyValuePair<string, object>()
                        {
                            Key = "MetadataId",
                            Value = new Guid("00000000-0000-0000-0000-000000000000")
                        }
                }
        };

        // fire request
        IAsyncResult result = OrganizationService.BeginExecute(request, null, OrganizationService);

        // wait for response
        TaskFactory<OrganizationResponse> tf = new TaskFactory<OrganizationResponse>();
        OrganizationResponse response = await tf.FromAsync(result, iar => OrganizationService.EndExecute(result));

        // parse response
        EntityMetadata entities = (EntityMetadata)response["EntityMetadata"];
        return entities.Attributes.Select(attr => attr.LogicalName).ToList();
    }

我的第一个方法是调用实际的CRM。这失败了,因为我无法进行身份验证。我问了一个关于here的问题。我的第二种方法是模拟组织服务并针对我的模拟运行方法。像这样:

    private bool _callbackCalled = false;
    private SilverlightDataService _service;
    private List<string> names;

    [TestInitialize]
    public void SetUp()
    {
        IOrganizationService organizationService = A.Fake<IOrganizationService>();
        _service = new SilverlightDataService {OrganizationService = organizationService};

        IAsyncResult result = A.Fake<IAsyncResult>();
        A.CallTo(organizationService.BeginExecute(A<OrganizationRequest>.Ignored, A<AsyncCallback>.Ignored,
                                                  A<object>.Ignored)).WithReturnType<IAsyncResult>().Returns(result);

        EntityMetadata entities = new EntityMetadata();
        AttributeMetadata meta = new AttributeMetadata();
        meta.LogicalName = "foobar";
        entities.Attributes = new ObservableCollection<AttributeMetadata>();
        entities.Attributes.Add(meta);
        OrganizationResponse response = new OrganizationResponse();
        response.Results = new ParameterCollection();
        response["EntityMetadata"] = entities;


        A.CallTo(() => result.IsCompleted).Returns(true);
        A.CallTo(result.AsyncState).WithReturnType<object>().Returns(response);
        A.CallTo(organizationService.EndExecute(result)).WithReturnType<OrganizationResponse>().Returns(response);
    }


    [TestMethod]
    [Asynchronous]
    public async void TestGetAttributeNamesOfEntity()
    {
        TaskFactory<List<string>> tf = new TaskFactory<List<string>>();
        names = await tf.FromAsync(_service.GetAttributeNamesOfEntity("avobase_tradeorder"), CallbackFunction);

        Assert.IsTrue(_callbackCalled);
        Assert.IsNotNull(names);
    }

    /// <summary>
    /// is used as callback for the method GetAttributeNamesOfEntity
    /// </summary>
    /// <param name="result"></param>
    /// <returns></returns>
    private List<string> CallbackFunction(IAsyncResult result)
    {
        _callbackCalled = true;
        names = (List<string>) result.AsyncState;
        return null;
    }

我使用FakeItEasy进行嘲弄。当我执行此测试(使用ReSharper和AgUnit)时,它会永远等待。我也尝试了this approach,但它没有用。

1)我的假设是我的嘲笑不会告诉等待魔法任务实际完成。为什么等待永远不会结束?我该怎么做才能解决这个问题?

2)有没有更好的方法来做到这一点?

编辑:我正在使用:通过NuGet安装VS 2012 Premium,ReSharper 7.1,Silverlight 5,AgUnit 0.7,.Net 4.5,FakeItEasy 1.13.1。

0 个答案:

没有答案
相关问题