【问题标题】:MOQ Exception Was unhandled by user用户未处理 MOQ 异常
【发布时间】:2016-08-23 04:01:50
【问题描述】:

我对 MOQ 很陌生,现在正在学习。我得到了需要编写单元测试的任务但是我得到了以下我无法找到的错误。请任何人帮我解决这个问题。如果我的测试用例需要更改,请查看代码并给我一些建议。

期望:IAcronisService.GetActivitiesFromDate("mygroup", 5/24/2016 8:33:34 PM)调用失败,模拟行为严格.....

对于Save方法(我已经在抛出异常的save方法上发表了评论)

处理方法调用保存方法

public int Process()
{
    AcronisService = AcronisSvcManager.Get(ClientFactory, DataProviderFactory, LogAdapter);

    DataObject backupGroupsDO = GetListOfAllCurrentGroups();

    int activitiesSavedCount = Save(backupGroupsDO);
    return activitiesSavedCount;
}

当我调试时,当我将鼠标悬停在上述处理方法的第一行时,我也看到了下面的行。我认为服务对象没有调用/模拟。这与上述异常有关吗?请提出一些更改建议。

(IAcronisServiceProxy)AcronisService).AcronisURL 抛出了 MOQ.MockException 类型的异常。

保存方法

private int Save(DataObject backupGroupsDO)
{
    int count = 0;

    foreach (DataRecord dr in backupGroupsDO.DataRecord)
    {
        BackupGroup backupGroup = new BackupGroup(dr);

        // Get all activities for each group
        AcronisClient.DataModel.Activity.ActivitiesResponse acronisActivities;
        if (backupGroup.LastActivityDate == null)
        {
            // Get all activities for each group
            ***//Got Exception at this line***
            acronisActivities = AcronisService.GetActivitiesFromDate(backupGroup.GroupName, DateTime.Now.AddDays(-90)); 
        }
        else
        {
            acronisActivities = AcronisService.GetActivitiesFromDate(backupGroup.GroupName, backupGroup.LastActivityDate);
        }



        if (acronisActivities == null || acronisActivities.Activities == null)
        {
            // Stop processing b/c might be an issue with the connection to Acronis
            LogAdapter.LogError(KCBLog.Main, "Stopped processing activities, possible Acronis connection issue with getting Activities");
            return -1;
        }
        var lastBackUpActivity = acronisActivities.Activities.OrderByDescending(z => z.StartTime).FirstOrDefault();

        List<string> lastSuccessfulActivities = new List<string>();
        List<string> lastActivities = new List<string>();

        foreach (var acronisActivity in acronisActivities.Activities)
        {

            Kaseya.KCB.Common.DataModels.AcronisActivity activity = new AcronisActivity();
            activity.BackupPlanId = acronisActivity.BackupPlanId;
            activity.BytesProcessed = acronisActivity.BytesProcessed;
            activity.BytesSaved = acronisActivity.BytesSaved;


            activity.Cause = acronisActivity.CompletionResult == null ? null : acronisActivity.CompletionResult.Cause;
            activity.Reason = acronisActivity.CompletionResult == null ? null : acronisActivity.CompletionResult.Reason;
            activity.Effect = acronisActivity.CompletionResult == null ? null : acronisActivity.CompletionResult.Effect;

            activity.DateCreated = DateTime.Now;

            activity.FinishTime = acronisActivity.FinishTime;
            activity.GroupId = backupGroup.Id;
            activity.Id = acronisActivity.Id;
            activity.InitiatedBy = acronisActivity.InitiatedBy;
            activity.InstanceId = acronisActivity.InstanceId;
            activity.IsRootActivity = (bool)acronisActivity.IsRootActivity;
            activity.ParentActivityId = acronisActivity.ParentActivityId;
            activity.PartitionId = PartitionId;
            activity.StartTime = acronisActivity.StartTime;
            activity.State = acronisActivity.State;
            activity.Status = acronisActivity.Status;
            activity.Title = acronisActivity.Title;
            activity.UpdateTime = acronisActivity.UpdateTime;

            AcronisActivityDataProvider.AddUpdateAcronisActivity(activity);

            AcronisClient.DataModel.Activity.Activity lastSuccessfulActivity = acronisActivities.Activities.Where(z => z.Status == "ok" && z.Title.Contains("Running backup plan") && z.InstanceId==acronisActivity.InstanceId).OrderByDescending(z => z.FinishTime).FirstOrDefault();
            var lastActivity = acronisActivities.Activities.Where(z => z.Title.Contains("Running backup plan") && z.InstanceId == acronisActivity.InstanceId).OrderByDescending(z => z.FinishTime).FirstOrDefault();


            if (!string.IsNullOrEmpty(acronisActivity.InstanceId))
            {
                DataRecord assetDR = AssetDataProvider.GetByInstanceId(acronisActivity.InstanceId, PartitionId);
                if (assetDR != null)
                {
                    var assetId = assetDR.FindValue<string>("id", "");

                    if (lastSuccessfulActivity != null && !lastSuccessfulActivities.Contains(acronisActivity.InstanceId))
                    {
                        AssetDataProvider.UpdateLastSuccessfulActivityId(assetId, lastSuccessfulActivity.ParentActivityId);
                        lastSuccessfulActivities.Add(acronisActivity.InstanceId);
                    }
                    if (lastActivity != null && !lastActivities.Contains(acronisActivity.InstanceId))
                    {
                        AssetDataProvider.UpdateLastActivityId(assetId, lastActivity.ParentActivityId);
                        lastActivities.Add(acronisActivity.InstanceId);
                    }
                }
            }
            count++;
        }

        if (acronisActivities.Activities != null && acronisActivities.Activities.Count>0)
        {
            //backupGroup.LastActivityDate = lastBackUpActivity.StartTime;
            BackupGroupDataProvider.UpdateLastBackupGroupActivityDate(backupGroup.Id, lastBackUpActivity.StartTime);
        }
    }

    return count;
}

我写的测试方法,

public void Test()
{
    string groupName = "mygroup";
    string mybackupAccountName = "mybackupaccount";
    decimal PartitionId = 9m;
    DateTime lastActivityDate = DateTime.Parse("2016-08-14T20:47:05");
    string instanceId = "utinstanceId";
    string assetId = "123";


    DataRecord asset = new DataRecord();
    asset.AddField("id", 123);

    DataObject backupGroupsDO = new DataObject();
    DataRecord groupDataRecord = new DataRecord();
    groupDataRecord.AddField("id", 123);
    groupDataRecord.AddField("partitionId", PartitionId);
    groupDataRecord.AddField("groupName", groupName);

    //groupDataRecord.AddField("lastActivityDate", lastActivityDate);

    groupDataRecord.AddField("backupAccountName", mybackupAccountName);
    backupGroupsDO.DataRecord.Add(groupDataRecord);

    AcronisActivity acronisActivity = new AcronisActivity();
    acronisActivity.BackupPlanId = "utBackupPlanId";

    ActivitiesResponse activitiesResponse = new ActivitiesResponse();
    AcronisClient.DataModel.Activity.Activity activity = new AcronisClient.DataModel.Activity.Activity();
    activity.BackupPlanId = "utackupPlanId";
    activity.BytesProcessed = 124674;
    activity.BytesSaved = 06446;
    activity.CompletionResult = new CompletionResult()
    {
        Cause = "utCause",
        Reason = "utReason",
        Effect = "utEffect"
    };
    activity.FinishTime = DateTime.Parse("2016-08-14T20:47:04");
    activity.Id = "utId";
    activity.InitiatedBy = "utInitiatedBy";
    activity.InstanceId = "utInstanceId";
    activity.IsRootActivity = true;
    activity.ParentActivityId = "utParentActivityId";
    activity.StartTime = DateTime.Parse("2016-08-14T20:47:02");
    activity.State = "utState";
    activity.Status = "utStatus";
    activity.Title = "utTitle";
    activity.UpdateTime = DateTime.Parse("2016-08-14T20:47:03");

    activitiesResponse.Activities = new List<AcronisClient.DataModel.Activity.Activity>();
    activitiesResponse.Activities.Add(activity);

    var moqFactory = new MockRepository(MockBehavior.Strict);

    var moqDataProviderFactory = moqFactory.Create<IDataProviderFactory>();
    var moqDataProvider = moqFactory.Create<IDataProvider>();
    var moqLogAdapter = moqFactory.Create<ILogAdapter>();
    var moqAcronisServiceManager = moqFactory.Create<IAcronisServiceManager>();
    var moqAcronisService = moqFactory.Create<IAcronisService>();
    var moqAssetDataProvider = moqFactory.Create<IAssetDataProvider>();
    var moqAcronisActivityDataProvider = moqFactory.Create<IAcronisActivityDataProvider>();
    var moqBackupGroupDataProvider = moqFactory.Create<IBackupGroupDataProvider>();


    Credential MSPCredential = new Credential();

    moqDataProviderFactory.Setup(m => m.BackupGroupDataProvider.GetBackupGroups()).Returns(backupGroupsDO);

    moqAcronisServiceManager.Setup(m => m.Get(It.IsAny<IRestClientFactory>(), It.IsAny<IDataProviderFactory>(), It.IsAny<ILogAdapter>(), "")).Returns(moqAcronisService.Object);

    moqDataProvider.Setup(m => m.VerifyPartitionId(ref PartitionId));
    moqDataProvider.Setup(m => m.ExecuteNonQuery(It.IsAny<AddUpdateAcronisActivity>())).Returns(1);
    moqAcronisService.Setup(m => m.GetActivitiesFromDate(groupName, lastActivityDate)).Returns(activitiesResponse);
    moqAcronisActivityDataProvider.Setup(m => m.AddUpdateAcronisActivity(acronisActivity));
    moqAssetDataProvider.Setup(m => m.GetByInstanceId(instanceId, PartitionId,1)).Returns(asset);
    moqAssetDataProvider.Setup(m => m.UpdateLastActivityId(assetId, activity.ParentActivityId));
    moqAssetDataProvider.Setup(m => m.UpdateLastSuccessfulActivityId(assetId, activity.ParentActivityId));
    moqBackupGroupDataProvider.Setup(m => m.UpdateLastBackupGroupActivityDate("1234", lastActivityDate));

    // moqAcronisService.Setup(m => m.GetActivitiesFromDate(groupName, Convert.ToDateTime("2016-08-18T13:18:40.000Z"))).Returns(activitiesResponse);


    ActivityHarvester activityHarvester = new ActivityHarvester();

    activityHarvester.PartitionId = PartitionId;
    activityHarvester.DataProvider = moqDataProvider.Object;
    activityHarvester.LogAdapter = moqLogAdapter.Object;
    activityHarvester.AcronisSvcManager = moqAcronisServiceManager.Object;
    activityHarvester.DataProviderFactory = moqDataProviderFactory.Object;
    activityHarvester.AcronisService = moqAcronisService.Object;
    activityHarvester.AssetDataProvider = moqAssetDataProvider.Object;
    activityHarvester.BackupGroupDataProvider = moqBackupGroupDataProvider.Object;
    activityHarvester.AcronisActivityDataProvider = moqAcronisActivityDataProvider.Object;


    activityHarvester.process();//*process method calls above save method method* 
    moqFactory.VerifyAll();
}

【问题讨论】:

  • 目前尚不清楚(至少对我而言)您要测试什么。这么少的提示。使用一些Test Naming Convention。使用 Arrange-Act-Assert 模式在 UnitTest 方法中排列和格式化代码。对于错误,请查看例如here.

标签: c# unit-testing moq moq-3


【解决方案1】:

从您的示例中,您对IAcronisService.GetActivitiesFromDate 的设置表明它期望基于代码的lastActivityDate2016-08-14T20:47:05,但错误表明您使用的日期5/24/2016 8:33:34 PM 与预期不同。由于最小起订量行为是Strict,因此

导致模拟总是为没有相应设置的调用抛出异常。

您可以使用It.IsAny&lt;DateTime&gt;() 使设置更加灵活

moqAcronisService
    .Setup(m => m.GetActivitiesFromDate(groupName, It.IsAny<DateTime>()))
    .Returns(activitiesResponse);

或将您的起订量工厂中的行为更改为使用 DefaultLoose MockBehavior。

【讨论】:

  • 谢谢。这样可行。我遇到了同样的错误,并且采用了相同的策略。谢谢
  • 好酷。乐意效劳。如果这解决了您的问题,请不要忘记将其标记为已回答。
  • 所以对于同样的测试方法,我已经覆盖了If条件。但我还需要涵盖 else 条件,我知道该怎么做。而不是发送空值,只需要传递一些值。然后它转到其他条件。为此,我需要通过添加一行/分配值来编写相同的测试方法。我的问题是,有什么方法可以让我们只从外部传递值,而不是为一行编写相同的测试方法?
  • 在您的测试中创建一个包含通用代码的设置方法。然后在您的目标测试方法中调用通用设置,并执行该测试所需的特定设置以避免重复代码。
  • 如果可能的话,您能否提供一些我可以查看的参考/链接?我不知道该怎么做?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多