This is a migrated thread and some comments may be shown as answers.

Need a little help Mocking an Open Access operation

6 Answers 47 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Jeff
Top achievements
Rank 1
Jeff asked on 29 Nov 2012, 08:21 PM
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.

6 Answers, 1 is accepted

Sort by
0
Kaloyan
Telerik team
answered on 30 Nov 2012, 01:28 PM
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.
0
Jeff
Top achievements
Rank 1
answered on 30 Nov 2012, 04:44 PM
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.
0
Jeff
Top achievements
Rank 1
answered on 06 Dec 2012, 01:22 PM
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.


0
Jeff
Top achievements
Rank 1
answered on 06 Dec 2012, 01:52 PM
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.

0
Jeff
Top achievements
Rank 1
answered on 06 Dec 2012, 02:19 PM
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.

0
Ricky
Telerik team
answered on 11 Dec 2012, 04:49 AM
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.
Tags
General Discussions
Asked by
Jeff
Top achievements
Rank 1
Answers by
Kaloyan
Telerik team
Jeff
Top achievements
Rank 1
Ricky
Telerik team
Share this question
or