C# 防止在另一个方法的单元测试中调用void方法

C# 防止在另一个方法的单元测试中调用void方法,c#,unit-testing,rhino-mocks,C#,Unit Testing,Rhino Mocks,我正在尝试单元测试一个调用了另一个方法的方法。在这个内部方法中,数据库被访问以持久化数据,这就是为什么我需要阻止它被实际调用。但是下面的代码没有实现这一点 试验 在这个AssignToActionTemplate中,我将一些数据持久化到数据库中,这就是我希望防止被调用的内容。有没有办法做到这一点 谢谢 编辑: 根据Phil Sandler的评论 在DelferralService的计划中,条目是根据DelferralRequest从工厂获取的(我在代码中添加了一些行)您正在模拟一个具体的类,这在

我正在尝试单元测试一个调用了另一个方法的方法。在这个内部方法中,数据库被访问以持久化数据,这就是为什么我需要阻止它被实际调用。但是下面的代码没有实现这一点

试验

在这个AssignToActionTemplate中,我将一些数据持久化到数据库中,这就是我希望防止被调用的内容。有没有办法做到这一点

谢谢

编辑:

根据Phil Sandler的评论


在DelferralService的计划中,条目是根据DelferralRequest从工厂获取的(我在代码中添加了一些行)

您正在模拟一个具体的类,这在.Net中通常很困难。见‘’


如果您可以为Entry创建一个接口,并使被测试的类依赖于该接口,那么测试(通过模拟)将更加容易

不幸的是,在这个解决方案中我无法做到这一点。这不是另一种解决方法吗?这两种方法都是虚拟的,但很明显你是对的,具体的类出了问题。理解Phil向我指出的困难,我重构了这些东西(tbh我只是试图在解决方案中模仿其他糟糕的编码“模式”),然后我将该方法移动到一个服务中,而不是在类中使用它(它有几十种方法)。然后我可以轻松地模拟新服务并存根该方法(这是正确的措辞吗?)听起来你已经解决了。如果不是这样,你能发布更多的代码吗?我不清楚延迟服务是如何使用条目的。谢谢@Phil Sandler,是的,我对它进行了排序。事实上,我没有排序,因为我选择了不同的路径,但我没有尝试任何其他方法,实际上更改了代码。
[Test]
public void Schedule_WhenEntryIsAvailable()
{
    #region Arrange
    var entryStub= MockRepository.GenerateStub<Entry>();

    _entryDal.Stub(_ => _.Retrieve(Arg<long>.Is.Anything)).Return(entryStub);
    entryStub.Stub(_ => _.AssignToActionTemplate(Arg<ActionTemplates>.Is.Anything, Arg<long>.Is.Anything, Arg<IUnitOfWork>.Is.Anything));          
    #endregion

    #region act
    //I create the deferralRequest

    _deferralService.Schedule(deferralRequest);
    #endregion

    #region assert
    //...
    #endregion
}
public virtual void Schedule(DeferralRequestDto deferralRequest, bool ignoreSeasonal = false)
{
    if (!deferralRequest.Deferrals.Any()) return;

    if (Validate(deferralRequest, ValidationGroup.PersonValidation & ValidationGroup.EntryValidation))
    {

        foreach (var deferral in deferralRequest.Deferrals)
        {
            var entryFromRequest= EntryFactory.Factory(_entryDal.Retrieve(deferral.Id));

           /.... Do different things

           var deferToEntry = CreateDeferralEntry(deferral, deferFromEntry, deferralRequest.UserId);
        }
    }
}

private Entry CreateDeferralEntry(Deferral deferral, Entry @entry, long userId)
{
    var deferFromEntry = @entry.GetGentleEntity(); //We're using Gentle as persistent framework

        var deferEntry = new entry
        {
            //We populate the deferEntry using the deferFromEntry fetched and the deferral from the parameters
        };

    //And after a few thing we call this method that actually persist to the an action table in the db which is the bit I would like to avoid being called
    deferToEntry.AssignToActionTemplate(ActionTemplates.Deferral, deferEntry.CreatedBy, null); 

    return deferToEntry;
}