Need a little help Mocking an Open Access operation

7 posts, 0 answers
  1. Jeff
    Jeff avatar
    10 posts
    Member since:
    Oct 2010

    Posted 29 Nov 2012 Link to this post

    Hi!

    I new to doing Test Driven Development.  I have a class factory that I am writing tests for.  The class factory returns a different type of class depending on the underlying properties of the persistence in the data layer.  The data layer is being implemented in an OpenAccess Model.

    Here is an example set of code:

    public class FooFactory
    {
        public static IFoo CreateFoo(int barKey)
        {
            using (FooBarModel foom = new FooBarModel())
            {
                Bar barEntity = foom.Bars.Where(n => n.BarKey == barKey).FirstOrDefault();
                // For this example, I will assume the bar record always exists.
                if (barEntity.IsIron)
                {
                    return new IronFoo();
                }
                else if (barEntity.IsGold)
                {
                    return new GoldenFoo();
                }
                else
                {
                    return new LeadFoo();
                }
            }
        }
    }

    How do I go about setting up a Mock so that instead of the FooBarModel being directly called, I can have mocked type used that specifies the barEntity.IsIron property returns true?

    I do have another way I can go about this, but I don't really like it.  I may also be missing the main idea on how to use the JustMock.

    Thanks,
    j.
  2. Kaloyan
    Admin
    Kaloyan avatar
    872 posts

    Posted 30 Nov 2012 Link to this post

    Hi Jeff,

    Thank you for contacting us about your issue.

    As I can see from the code sample you have provided, you will need to create mock object of your "Bar" class like this:
    var barMock = Mock.Create<Bar>();

    After creating the mock, you will have to arrange its behavior so that  its "Bar.IsIron" property returns "true". You could do that the following way:
    Mock.Arrange(() => barMock.IsIron).IgnoreInstance().Returns(true);
    Note that, you will need to use the "IgnoreInstance()" method in order to apply future mocking to your "barMock". This is needed due to the fact you are using a new instance of the "FooBarModel" in your system under test. You can read more about this here.

    If I have misunderstood you with the case, you could find more information about faking the Open Access data access layer with JustMock, here

    I hope this solves your issue. If there is anything else, I could help you with, please do not hesitate to ask.

    Greetings,
    Kaloyan
    the Telerik team
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
  3. DevCraft R3 2016 release webinar banner
  4. Jeff
    Jeff avatar
    10 posts
    Member since:
    Oct 2010

    Posted 30 Nov 2012 Link to this post

    Hi Kaloyan!

    That worked brilliantly!  As always, the Telerik team never fails to impress! :)

    I just successfully used what you suggested, and now my test works!

    Thank you so much!

    j.
  5. Jeff
    Jeff avatar
    10 posts
    Member since:
    Oct 2010

    Posted 06 Dec 2012 Link to this post

    Apparently, I was overly optimistic about the solution.  For some reason my tests are now failing, and I have tracked it down to the OpenAccess model seems to be ignoring the Mock statements.

    Below is an example of my test (that was working 7 days ago :( ).
    [Test] //Using the Nunit framework
    public void GoldBarInstanceReturn()
    {
       // Arrange the bar mockup to be gold
       var bar = Mock.Create<Bar>();
       Mock.Arrange(() => bar.IsIron).IgnoreInstance().Return(false).MustBeCalled();
       Mock.Arrange(() => bar.IsGold).IgnoreInstance().Return(true).MustBeCalled();
     
       // Act
       IFoo foo = FooFactory.CreateFoo(GetFirstBarKey());  // GetFirstBarKey just returns the first entry of barKey in the Bars table.
     
       // Assert
       Mock.Assert(bar);  // Assert fails as the mock bar properties are not invoked.
       Assert.IsInstanceOf<GoldenFoo>(foo); // Assert fails as the first barkey in the bars table is NOT a golden foo.
    }
     
    private int GetFirstBarKey()
    {
       using(BarModel bm = new BarModel()
       {
           return bm.Bars.FirstOrDefault(n => n.BarKey > 0).BarKey;
       }
    }

    If you can offer guidance on what I am doing wrong, I would appreciate it.  We did make a change to data access layer to Aggregate the models together so that they could be used in conjunction with each other, but even undoing that modification does not seem to fix the problem.

    Thanks,
    j.


  6. Jeff
    Jeff avatar
    10 posts
    Member since:
    Oct 2010

    Posted 06 Dec 2012 Link to this post

    Ok, I think I found the root cause of the problem.  It turns out that I need to explicitly call the DisposeDatabase(); method on each instance of the model I am using during the test run.

    What is surprising is the fact that every Open Access Model I am using is wrapped in a 'using' statement, which calls the Dispose() method on the model.  I would expect that the Dispose method would cause the DisposeDatabase method to be invoked, but that does not seem to be the case.

  7. Jeff
    Jeff avatar
    10 posts
    Member since:
    Oct 2010

    Posted 06 Dec 2012 Link to this post

    Alright, I have a new question.  In my model, I have a stored procedure call which returns a value through one of the parameters. 

    The code for calling the model looks like this:
    public bool HasMatter(int barKey)
    {
      using(BarModel bm = new BarModel())
      {
        int? hasMatter = 0;
        bm.sp_CheckMatterState(barKey, ref hasMatter);  // It is the return value into hasMatter I want to mock, so I can test
        bm.DisposeDatabase();
        return (hasMatter != 0);
      }
    }


    What is the best of way of mocking up the stored procedure call so I can control the value of the output parameter?

    Thanks,
    j.

  8. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 10 Dec 2012 Link to this post

    Hi Jeff,

    Thanks again for contacting us.

    Mocking out/ref works similar to returning a value. The idea is to set the expected the out / ref value when the method is called that will be used later in the flow. Considering the fact, I would write my test in the following way:
    [TestMethod]
    public void ShouldAssertThatHasMeterReturnsExpectedResultOnMatterState()
    {
        var myclass = Mock.Create<MyClass>(Behavior.CallOriginal);
     
        int? hasMeter = 1;
     
        Mock.Arrange(() => myclass.CheckMatterState(Arg.AnyInt, ref hasMeter)).MustBeCalled();
     
        bool actual = myclass.HasMatter(2);
     
        Assert.IsTrue(actual);
     
        Mock.Assert(myclass);
    }


    Hope this answers your question.

    Kind Regards
    Mehfuz
    Share what you think about JustTrace & JustMock with us, so we can become even better! You can use the built-in feedback tool inside JustTrace, our forums, or our JustTrace or JustMock portals.
Back to Top
DevCraft R3 2016 release webinar banner