0

I'm trying to unit test a method in which another method is being called. In this inner method the db is accessed to persist the data and that's why I'd need to prevent it to be actually called. But the following code doesn't achieve that.

Test

[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
}

Being the Schedule method in the Entry class

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;
}

It's inside this AssignToActionTemplate where I persist some data to the database and that's what I would like to prevent from being called. Is there a way to do so?

Thanks

EDIT:

As per Phil Sandler comment,

In the deferralService's Schedule the entry is fetched from a factory based on the deferralRequest (I add some lines in the code)

mitomed
  • 2,006
  • 2
  • 29
  • 58
  • Understanding the difficult Phil pointed to me I refactored this stuff (tbh I was just trying to mimic other bad coding "pattern" in the solution) and I moved that method to a service instead of using it in the class (wich turns to have dozens of methods). Then I can easilly mock the new service and stub the method (is this the correct wording?) – mitomed Feb 12 '14 at 14:52
  • Sounds like you have it solved. If that's not the case, can you post more code? I'm not clear on how deferralService uses Entry. – Phil Sandler Feb 13 '14 at 00:57
  • Thanks @Phil Sandler, yes I sorted it. In reality didn't sort it because I took a different path but I didn't try anything else and actually changed the code. – mitomed Feb 13 '14 at 10:21

1 Answers1

1

You are mocking a concrete class, which is generally difficult in .Net. See 'Is it recommended to mock concrete class.'

If you can create an interface for Entry and make the class under test dependent on the interface instead, it will make testing (via mocking) much easier.

Community
  • 1
  • 1
Phil Sandler
  • 27,544
  • 21
  • 86
  • 147
  • Unfortunately it's not something I could do in this solution. Is not other way of fixing this? both methods are virtual but obviously you're right in that something's going wrong with the concrete class. – mitomed Feb 12 '14 at 14:05