chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi, I'm trying to use TypeMock to mock a complex scenario that includes Singleton, Static , Interfaces and inner classes combined.

I'm trying to mock the return value of DataManager.Raw.CurrentStudy.GetRunByFrame(frame) which is a dependancy in a class I'm testing.
Here is the stripped down version:

using NUnit.Framework;
using TypeMock;

public class TesterClass
{
    public void TestGetRun()
    {
        FrameEntity frame = new FrameEntity();
        Run run = DataManager.Raw.CurrentStudy.GetRunByFrame(frame);
    }
}

[TestFixture]
public class Test
{
    [Test]
    public void TestMe()
    {
        MockManager.Init();
        Mock dataManager = MockManager.Mock(typeof(DataManager));
        Mock rawDataManager = MockManager.Mock(typeof(RawDataManager));
        Mock rawFacade = MockManager.Mock(typeof(DataManager.RawFacade));
        Mock iRawDataManager = MockManager.MockObject(typeof(IRawDataManager));
        Mock study = MockManager.Mock(typeof(StudyEntity));
        Mock Run = MockManager.Mock(typeof(Run));
        TesterClass tester = new TesterClass();
        dataManager.ExpectGet("Raw", rawDataManager.MockedInstance);
        iRawDataManager.ExpectGet("CurrentStudy", study.MockedInstance);
        rawDataManager.ExpectGet("CurrentStudy", study.MockedInstance);
        rawFacade.ExpectGet("CurrentStudy", study.MockedInstance);
        study.ExpectAndReturn("GetRunByFrame", Run.MockedInstance, null);

        tester.TestGetRun();
    }
}

public sealed class DataManager
{
    private RawDataManager rawDataManager;
    private RawFacade rawFacade;

    public static readonly DataManager Instance = new DataManager();

    public static IRawDataManager Raw
    {
        get
        {
            return Instance.rawFacade;
        }
    }

    private DataManager()
    {
        rawFacade = new RawFacade(this);
        rawDataManager = new RawDataManager();
    }

    private StudyEntity CurrentStudy
    {
        get
        {
            return rawDataManager.CurrentStudy;
        }
    }

    private void SetStudy(StudyEntity newStudy)
    {
        rawDataManager.SetStudy(newStudy);
    }

    internal class RawFacade : IRawDataManager
    {
        DataManager currentDM;

        public RawFacade(DataManager currentParent)
        {
            currentDM = currentParent;
        }

        public StudyEntity CurrentStudy
        {
            get
            {
                return currentDM.CurrentStudy;
            }
        }

        public void SetStudy(StudyEntity newStudy)
        {
            currentDM.SetStudy(newStudy);
        }
    }
}

public interface IRawDataManager
{
    StudyEntity CurrentStudy { get; }
    void SetStudy(StudyEntity newStudy);
}

public class RawDataManager : IRawDataManager
{

    private StudyEntity study;

    public RawDataManager()
    {
    }

    public StudyEntity CurrentStudy
    {
        get
        {
            return study;
        }
        set
        {
            study = value;
        }
    }

    public void SetStudy(StudyEntity newStudy)
    {
        study = newStudy;
    }
}

public class StudyEntity
{
    public StudyEntity(Run run)
    {
        this.run = run;
    }
   
    private Run run;

    public Run GetRunByFrame(FrameEntity frame)
    {
        return run;
    }
}

public class FrameEntity
{
}

public class Run
{
    public Run()
    {

    }
}


How do I mock this using reflective type mock (the community edition)?
If this is not testable using the community edition but is using Professional Standard, is there way for me to test this pior to purchasing a license (When trying to use demo I get an exception that says:
*** You are using the Demo version that allows only one Mock, to enable please enter license key.
asked by shmulikprimes (720 points)

6 Answers

0 votes
Natural Mocks is the way to go,
I will send you an evaluation license via you e-mail
answered by scott (32k points)
0 votes
It is obvious that this is the way to go.
The question is how can this be done using reflective mocking.
answered by shmulikprimes (720 points)
0 votes
Hi,

Here is how you do it in Reflective Mocks
[Test]
public void TestMe()
{
  MockManager.Init();
  Mock dataManager = MockManager.Mock(typeof(DataManager));
  MockObject rawDataManager = MockManager.MockObject(typeof(IRawDataManager));
  MockObject study = MockManager.MockObject(typeof(StudyEntity));
  MockObject run = MockManager.MockObject(typeof(Run));
  dataManager.ExpectGet("Raw", rawDataManager.Object);
  rawDataManager.ExpectGet("CurrentStudy", study.Object);
  study.ExpectAndReturn("GetRunByFrame", run.Object);

  TesterClass tester = new TesterClass();
  tester.TestGetRun();
}


and here in Natural Mocks
[Test]
public void TestMe()
{
    using (RecordExpectations record = RecorderManager.StartRecording())
    {
        DataManager.Raw.CurrentStudy.GetRunByFrame(null);
    }
    
    TesterClass tester = new TesterClass();
    tester.TestGetRun();
}
answered by scott (32k points)
0 votes
Thanks for the swift reply Scott, it works!

Now for me to understand this better (The API reference on MockObject is not clear):
I understand why the Mock for IRawDataManager needs MockObject instead of Mock, but why are the constructors for Study and Run also using MockObject and not Mock?
Is there a clear guideline on when to use Mock vs. MockObject?
answered by shmulikprimes (720 points)
0 votes
Hmm,
Perhaps we should explain better.
A Mock will mock a future instance (where a constructor is called somewhere in the tested code)
A MockObject will create the instance immediately and mock it. You can then pass the instance (mock.Object).

When mocking chained calls it is best practice to use MockObjects as the return value. This will ensure that the correct instance is returned.
answered by scott (32k points)
0 votes
Thanks
answered by shmulikprimes (720 points)
...