Is it possible to "increment" an arrangement

9 posts, 1 answers
  1. Dave
    Dave avatar
    31 posts
    Member since:
    Apr 2014

    Posted 16 Mar 2015 Link to this post

    Suppose I have a class MyClass, with a method MyMethod(), and I have a method under test which looks something like:
    MethodUnderTest(MyClass myClass)
    {
        myClass.MyMethod();
        // Do some other stuff
        myClass.MyMethod();
    }


    I would like to be able to write the test for this looking something like:
    [TestMethod]
    public void MyTest()
    {
        MyClass mockMyClass = Mock.Create<MyClass>(Behaviour.Strict);
        mockMyClass.Arrange(x=>x.MyMethod());
        // Arrange the other stuff
        mockMyClass.Arrange(x=>x.MyMethod());
     
        MethodUnderTest(mockMyClass);
         mockMyClass.AssertAll();
    }


    Of course I cannot do this, as the second Arrange simply replaces the first. I have to do:
    [TestMethod]
    public void MyTest()
    {
        MyClass mockMyClass = Mock.Create<MyClass>(Behaviour.Strict);
        mockMyClass.Arrange(x=>x.MyMethod(), 2);
        // Arrange the other stuff
     
        MethodUnderTest(mockMyClass);
         mockMyClass.AssertAll();
    }


    which is OK, but the first pattern is a better reflection of the structure of the test and the method being tested, and is thus more readable.

    Is there a syntax which allows me to say "arrange another call to this method" and so looks more like the first test and less like the second?

    Dave
  2. Dave
    Dave avatar
    31 posts
    Member since:
    Apr 2014

    Posted 16 Mar 2015 in reply to Dave Link to this post

    Of course, for
        mockMyClass.Arrange(x=>x.MyMethod(), 2);
    read
        mockMyClass.Arrange(x=>x.MyMethod()).Occurs(2);

    my error.
  3. DevCraft R3 2016 release webinar banner
  4. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 17 Mar 2015 Link to this post

    Hi Dave,

    I think what you are looking for is asserting the order of execution. Here's the doc on that. Here's how it would apply to your test:

    mockMyClass.Arrange(x=>x.MyMethod()).InOrder();
    // Arrange the other stuff, possibly again InOrder()
    mockMyClass.Arrange(x=>x.MyMethod()).InOrder();


    Regards,
    Stefan
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  5. Dave
    Dave avatar
    31 posts
    Member since:
    Apr 2014

    Posted 20 Mar 2015 in reply to Stefan Link to this post

    Thanks Stefan, but I can't get this to work. I have put together a small test project which you can download from http://www.knoware.co.uk/TestInOrderProblem.zip. I would be most grateful if you could have a look at it and tell me what I am doing wrong.
  6. Answer
    Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 24 Mar 2015 Link to this post

    Hi Dave,

    I took a look at your tests and it seems what you need is not InOrder(), but InSequence().

    Here's your preferred test, updated to work correctly:
    [TestMethod]
    public void ThisIsWhatIWantToDo_ShouldWorkButDoesnt()
    {
        _classToBeMocked.Arrange(x => x.Method1()).InSequence().OccursOnce();
        _classToBeMocked.Arrange(x => x.Method2()).OccursOnce();
        _classToBeMocked.Arrange(x => x.Method3()).OccursOnce();
        _classToBeMocked.Arrange(x => x.Method1()).InSequence().OccursOnce();
     
        _classToBeTested.MethodToBeTested();
     
        _classToBeMocked.AssertAll();
    }

    Further information about sequential mocking can be found in the documentation.

    Regards,
    Stefan
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  7. Dave
    Dave avatar
    31 posts
    Member since:
    Apr 2014

    Posted 26 Mar 2015 in reply to Stefan Link to this post

    Stefan
    yes that works, thanks.
    I am quite confused as to the difference between InSequence() and InOrder(). Could you briefly explain the difference, and when you would use InOrder().
    Thanks
    Dave
  8. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 27 Mar 2015 Link to this post

    Hello Dave,

    InSequence() allows you to specify different behavior, e.g. different return values, for successive calls to the same member, e.g.:
    Mock.Arrange(() => DateTime.Now).Returns(DateTime.Now).InSequence();
    Mock.Arrange(() => DateTime.Now).Returns(DateTime.Now.AddDays(1)).InSequence();
    InOrder() allows you to assert the order of calls within a test. The assertion will fail if the arranged calls are executed out of the predefined order or not executed at all, e.g.:
    Mock.Arrange(() => db.BeginTransaction()).InOrder();
    Mock.Arrange(() => db.EndTransaction()).InOrder();
    Mock.Assert(db);


    Regards,
    Stefan
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
  9. Dave
    Dave avatar
    31 posts
    Member since:
    Apr 2014

    Posted 27 Mar 2015 in reply to Stefan Link to this post

    Hmm. That was my understanding. However what my example is doing would seem to be exactly what InOrder (rather than InSequence) is used for. I guess it's just a matter of trying both and seeing which works in a given situation.
  10. Stefan
    Admin
    Stefan avatar
    198 posts

    Posted 01 Apr 2015 Link to this post

    Hi Dave,

    If you want to use InOrder() multiple times on the same member, you actually need to combine it with InSequence(), like so:

    mockMyClass.Arrange(x=>x.MyMethod()).InSequence().InOrder();
    // Arrange the other stuff, possibly again InOrder()
    mockMyClass.Arrange(x=>x.MyMethod()).InSequence().InOrder();

    I'm sorry that I missed this detail in my previous post.

    Regards,
    Stefan
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
Back to Top
DevCraft R3 2016 release webinar banner