A First Look at Moq 52

Posted by Brett Schuchert Wed, 20 May 2009 02:46:00 GMT

This week I’m working with a customer that uses two tools I have not previously used: MBUnit (instead of NUnit, and it is now part of Gallio [sic]) and Moq (by Daniel Cazzulino).

For how I’m using MBUnit, there are no differences (that’s not to say it’s the same as NUnit, I’m just using it that way). However, Moq is a different mocking framework.

While you can do something similar to a record/playback approach, Moq encourages a different approach. Rather than try to describe it, I’ll show a few examples and you can decide for yourself (or you can tell me how I should have done it better).

Background

Given a login service, I want to make sure it follows a set of requirements. The list of requirements I typically use for this example are here: http://schuchert.wikispaces.com/Tdd.Problems.LoggingIn. What follows are tests that are similar to, but not quite consistent with those requirements.
When I was working through this example, I was a little exception happy. I was trying to learn how to make certain things happen with the moq. I’ve simply repeated my experiments here, when I use this later on, I’ll approach this problem a bit differently.

Example 1: Logging in successfully

00: [Test]
01: public void WhenUserFoundAndPasswordMatchesUserShouldBeLoggedIn()
02: {
03:   var userMock = new Mock<IUser>();
04:   userMock.Setup(user => user.PasswordMatches(It.IsAny<string>())).Returns(true);
05:
06:   var daoMock = new Mock<IUserDao>();
07:   daoMock.Setup(dao => dao.Get(It.IsAny<string>())).Returns(userMock.Object);
08:
09:   var service = new UserService(daoMock.Object);
10:   service.Login("Brett", "password");
11:
12:   userMock.VerifySet(user => user.LoggedIn = true);
13: }
Line 3 Create a userMock.
Line 4 Using a C# lambad, when a user object is sent the PasswordMatched message with any string object, return true.
Line 6 Create a mock IUserDao.
Line 7 Whenever the Get method is called with any string, return the userMock’s Object property (the actual mock object).
Line 9 Create a user service and inject into it the daoMock’s Object property (the actual dao mock).
Line 10 Send the login message, which should result in the User being logged in.
Line 12 Verify that the LoggedIn property was set to true.

Notice that rather than setting expectations, line 12 verifies only what I want to verify. It is possible to call Setup more times and then use “VerifyAll” to confirm all the Setup’s were actually used. However, that makes the test more coupled to the underlying implementation. All I care about is that as a result of this configuration of objects, a user was LoggedIn.

By default, mocks are not strict. That is, code may call any methods it wishes on a give mock object. So the default behavior is more like a stub than a mock object. If you call “VerifyAll” on the userMock or the daoMock, then all of the descriptions in the various Setup method invocations need to happen.

Example 2: User not found? Throw an exception

00: [Test]
01: [ExpectedException(typeof(UserDoesNotExistException))]
02: public void WhenUserNotFoundShouldThrowException()
03: {
04:   var daoMock = new Mock<IUserDao>();
05:   daoMock.Setup(dao => dao.Get(It.IsAny<string>())).Returns((IUser) null);
06:
07:   var service = new UserService(daoMock.Object);
08:   service.Login("Brett", "password");
09: }
Line 1 Create an IUserDao mock.
Line 5 When Get is called with any string, return null – that is, never find an object. I think of this as a kind of Saboteur, which is a specific kind of stub.
Line 7 Create a user service and inject the daoMock.Object property, the actual mock.
Line 8 Call the Login method, which should throw an exception for this test to pass.

Notice that this example includes another non-strict mock. You can call it as often as you wish and there’s no checking on the methods called. However, this stub should force the implementation of the Login method to throw a UserDoesNotExist exception.

Example 3: Throw an Exception if the password does not match

00: [Test]
01: [ExpectedException(typeof(PasswordDoesNotMatchException))]
02: public void WhenLoginAttemptDoesNotMatchPasswordThrowsException()
03: {
04:   var userMock = new Mock<IUser>();
05:   userMock.Setup(user => user.PasswordMatches(It.IsAny<string>())).Returns(false);
06:
07:   var daoMock = new Mock<IUserDao>();
08:   daoMock.Setup(dao => dao.Get(It.IsAny<string>())).Returns(userMock.Object);
09:
10:   var service = new UserService(daoMock.Object);
11:   service.Login("", "");
12: }
Line 4 Create an IUser mock.
Line 5 Whenever the PasswordMatches method is called with any string, it will return false. All passwords are wrong!
Line 7 Create an IUserDao mock.
Line 8 Whenever Get is called with any string on the IUserDao mock object, return the userMock.Object property (the real mock object).
Line 10 Create a UserService, injecting the daoMock.Object property (the real IUserDao mock).
Line 11 Logging in with any user/password combination should now throw a PasswordDoesNotMatchException.

Eample 4: Three failed login attempts should cause user account to be revoked.

00: [Test]
01: public void WhenLoginAttemptThreeTimesInARowWithInvalidPasswordUserRevoked()
02: {
03:   var userMock = new Mock<IUser>();
04:   userMock.Setup(user => user.PasswordMatches(It.IsAny<string>())).Returns(false);
05: 
06:   var daoMock = new Mock<IUserDao>();
07:   daoMock.Setup(dao => dao.Get(It.IsAny<string>())).Returns(userMock.Object);
08:
09:   var service = new UserService(daoMock.Object);
10:   for (int i = 0; i < 3; ++i)
11:     AttempLoginIgnoringException(service, "");
12:   
13:   userMock.VerifySet(user => user.Revoked = true);
14: }
Lines 3 – 4 Create an IUser mock (stub or Saboteur really) that will not match any password.
Lines 6 – 7 Create an IUserDao mock (stub) that will return the userMock.Object for all calls to Get with any string.
Line 9 Create a UserService, injecting the IUserDao mock object.
Lines 10 – 11 Attempt to login 3 times, each of which will fail.
Line 13 Verify that the user.Revoked property was set to true on the userMock object.

Example 5: Failing 2x with one account and then switching to another account and failing again does not revoke account.

00: [Test]
01: public void LoginWrongPassword2XandThenSwitchAccountsWithWrongPassowrdNothingRevoked()
02: {
03:   var userMock1 = new Mock<IUser>();
04:   userMock1.Setup(user => user.PasswordMatches(It.IsAny<string>())).Returns(false);
05:
06:   var userMock2 = new Mock<IUser>(MockBehavior.Strict);
07:   userMock2.Setup(user => user.PasswordMatches(It.IsAny<string>())).Returns(false);
08: 
09:   var daoMock = new Mock<IUserDao>();
10:   daoMock.Setup(dao => dao.Get("user1")).Returns(userMock1.Object);
11:   daoMock.Setup(dao => dao.Get("user2")).Returns(userMock2.Object);
12:
13:   var service = new UserService(daoMock.Object);
14:
15:   AttempLoginIgnoringException(service, "user1");
16:   AttempLoginIgnoringException(service, "user1");
17:   AttempLoginIgnoringException(service, "user2");
18:
19:   userMock2.VerifyAll();
20: }
Lines 3 – 4 Create user mock that will not match any password.
Lines 6 – 7 Ibid, but this is a strict mock. That is, other than PasswordMatches, no other methods/properties should be called/used (we do not want it’s Revoked property to be set or even called).
Lines 9 – 11 Create an IUserDao mock. Whenever Get is called with “user1”, return userMock1.Object. Whenever Get is called with “user2”, return userMock2. Object.
Lines 12 Create the UserService injecting the daoMock.Object.
Lines 15 – 16 Attempt login 2x to account User1, both will fail.
Line 17 Attempt login to account User2, which will also fail, but we do not want the user2 account revoked.
Line 19 Verify all, meaning that only the PasswordMatches method was called on userMock2.Object. If any other methods were called, the test will fail.

Conclusion

That’s it for now. If you want to more examples or better explanations, or if you can tell me how to make these examples better, please let me know.
Comments

Leave a response

  1. Avatar
    Al Tenhundfeld about 12 hours later:

    I love Moq and am happy to see it get more exposure; I’d like to clarify some points.

    I don’t think Moq has any affiliation with Google other than being hosted on GoogleCode. To my knowledge, Moq is primarily a product of Dan Cazzulino (Kzu).

    Also, when Moq first came out in late 2007, the lambda and generics syntax was novel, but now the other popular .NET mocking frameworks (RhinoMocks, TypeMock Isolator) also support it. My point is just that this approach to mocking is feasible in other frameworks; although, I still find Moq to be the most intuitive framework for the TDD/classicist style of mocking.

  2. Avatar
    Robin Clowers about 14 hours later:

    Hi Bret, thanks for the good overview of Moq. One thing though, you said in your opening paragraph Moq is Google’s .net mocking framework. As far as I know, Google has no affiliation with the Moq project, it was started by Daniel Cazzulino of Clarius Consulting.

  3. Avatar
    Bill Sorensen about 15 hours later:

    Moq is my mocking library of choice; I find it very intuitive. I’m also pleased to see it getting more exposure.

  4. Avatar
    Brett L. Schuchert about 17 hours later:

    Al/Robin,

    Thanks for that! I’ll update the post.

  5. Avatar
    Daniel Cazzulino 1 day later:

    Indeed, calling Moq “Google’s mocking framework” is like calling ASP.NET MVC “Codeplex’s MVC framework”.

    Google just happens to be the project hoster, that’s it.

  6. Avatar
    Steve Py 1 day later:

    Moq became my mocking library of choice last year. My only irk was that like other open-source projects, they tend to make significant breaking-changes. (I.e. replacing the “Expect” & related methods with “Setup”) Not that I recall seeing any doco / explanation for the change, but then again we were content using v2.6 for quite some time.

  7. Avatar
    tieTYT 1 day later:

    Moq seems good. It reminds me of Mockito (a Java framework). I wonder if it was inspired by it.

  8. Avatar
    Daniel Cazzulino 5 days later:

    Steve, we do not make breaking changes ever (on purpose, anyway).

    The renaming of Expect to Setup was not breaking. If you had/have existing tests that use the Expect syntax, they continue to compile and run just fine. We just hide the obsoleted members so that new tests/users can start using the new syntax without the clutter of older APIs.

    Same with other things we changed. We can always miss a minor thing here and there when moving forward, but we always spend a good chunk of time in public beta to minimize this, incorporating user feedback.

    Thanks for choosing Moq!

  9. Avatar
    ??????? about 1 month later:

    ? ??? ? ????

  10. Avatar
    fdsaq 4 months later:

    asdf

  11. Avatar
    FLV extractor 11 months later:

    the article is so ....

  12. Avatar
    http://www.zigota.co.il/ 11 months later:

    ? ??? ??? ???? ?? ????!

    http://www.zigota.co.il/

  13. Avatar
    FLV to ipad converter 11 months later:

    just

  14. Avatar
    han 11 months later:

    http://www.ipadvideoconverters.biz iPad Video Converter iPad Video Converter is a great software for iPad lovers to convert videos to iPad with super fast speed and high quality. Its easy-to-use interface makes iPad to videos conversion routine very simple. And also it can keep the original quality of video files.

  15. Avatar
    Easy Date 12 months later:

    Find date the easy way!

  16. Avatar
    www.help.com about 1 year later:

    Help

  17. Avatar
    Lala about 1 year later:

    I think so.

  18. Avatar
    chanel jewelry about 1 year later:

    nice

  19. Avatar
    Pandora about 1 year later:

    I suppose the students who take our TDD course could claim to be Object Mentor Certified TDDers; and they’d be right.

  20. Avatar
    childcare jobs about 1 year later:

    Great set of resources – I think this is the biggest oversight of most people childcare jobs

  21. Avatar
    Easy Date about 1 year later:

    I have to agree with your opinion on that

  22. Avatar
    http://www.whiteiphone4transformer.com about 1 year later:

    Do you want the latest white iphone 4? Now we supply white iphone 4 Conversion Kit with elegant and delicate figures can surely be your best iphone 4 company.

  23. Avatar
    Silicone Molding about 1 year later:

    Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds, Intertech is also very professional for making flip top Cap Molds in the world.

  24. Avatar
    Sell Gold for Cash about 1 year later:

    The postings on Object Mentor are always excellent. Thanks for the great share and keep up this great work! All the best to you.

  25. Avatar
    dswehfhh about 1 year later:

    We are the professional jeans manufacturer, jeans supplier, jeans factory, custom jeans.

  26. Avatar
    Polo Ralph Lauren about 1 year later:

    That Polo Rob Lauren company offers take place far away which is right now the most well-known Boys Custom made Clothes makes on the earth. Grab yourself kitted up within some of the world’s good

  27. Avatar
    okey oyunu oyna about 1 year later:

    many thanks.

    internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.

  28. Avatar
    cheap brand watches about 1 year later:

    It is really a nice post, it is always great reading such posts, this post is good in regards of both knowledge as well as information. Very fascinating read, thanks for sharing this post here.

  29. Avatar
    adres zoeken op naam over 2 years later:

    Thanks for this post, will use it in class!

  30. Avatar
    http://www.topcartierlove.org/Cartier-Earring_3_1.htm over 2 years later:

    Thanks so much! I can not begin to explain how excited I am to wear this beauty around. It is utterly so unique and elegant. I will be sure to post modeling pics when it arrives.

  31. Avatar
    Cartier earring 2011 over 2 years later:

    I agree with you. I am amazed everyday by how really cool it is to be living in a time where we are all so accessible! I LOVE this. I always wonder why not everyone gets as excited by the tools we use the way I do. Truth is, I can’t imagine not having all the fun and abilities I explore and play with all the time.

  32. Avatar
    beats by dre store over 2 years later:

    I can’t imagine not having all the fun and abilities I explore and play with all the time.beats by dre sale cheap beats by dre

  33. Avatar
    beats by dr dre over 2 years later:

    gets as excited by the tools we use the way I do. Truth is, I can’t imagine not having all the fun and abilities I explore and play with all the time.beats by dr dre beats by dre sale

  34. Avatar
    xnxx over 2 years later:

    ha good, i wanted

  35. Avatar
    cyberknife over 2 years later:

    I suppose the students who take our TDD course could claim to be Object Mentor Certified TDDers; and they’d be right.It is really a nice post, it is always great reading such posts, this post is good in regards of both knowledge as well as information. Very fascinating read, thanks for sharing this post here.

  36. Avatar
    Diablo3 over 2 years later:

    Blog posts about wedding and bridal are always rare to find , at least with great quality,you qualify for a great blog post writer title,kep the great job happening

  37. Avatar
    shanewatson404@gmail.com over 2 years later:

    You guys are really wonderful technology is visible in this blog that to searching the nice info is visible in this blog. I am searching the different services in this Director of Operations Job Description blog and the interesting services in this blog Accounting Job Description This is really inspired the Graphic Designer Job Description great technology that to using the Legal Assistant Job Description amazing the info is visible in this blog

  38. Avatar
    MTS Convertisseur over 2 years later:

    Swing open the door, and behold a tableau that perfectly captures the tween aesthetic. The polka-dot chandelier. The zebra-print wallpaper. The lime green shag rug that pulls the look together — without being too matchy-matchy, as a pre-tween might have it. MTS Convertisseur But you can’t go in because the door doesn’t lead to a room. It leads to a locker. Specifically, Nola Storey’s locker at Rye Middle School in a New York suburb. MTS Convertisseur Mac

  39. Avatar
    Tips For Bowling over 2 years later:

    The general interest of the masses might take the place of the insight of genius if it were allowed freedom of action.

  40. Avatar
    ysbearing over 2 years later:

    Slewing bearing called slewing ring bearings, is a comprehensive load to bear a large bearing, can bear large axial, radial load and overturning moment.

  41. Avatar
    christian louboutin over 2 years later:

    Slewing bearing called slewing ring bearings, is a comprehensive load to bear a large bearing, can bear large axial, radial load and overturning moment.

  42. Avatar
    Arcteryx Jackets over 3 years later:

    http://www.arcteryxjackets-sale.com

  43. Avatar
    joburi gaming over 3 years later:

    I agree with you. I am amazed everyday by how really cool it is to be living in a time where we are all so accessible!

  44. Avatar
    find cell number over 3 years later:

    While most people could tell you the highest mountain in the world is Mount Everest and the longest river in the world is the Nile, not many people know much about the biggest lakes around the world.

    find cell number

  45. Avatar
    tequilaxxx over 3 years later:

    super !!

  46. Avatar
    iPhone contacts backup over 3 years later:

    It is really a good example that most of the programmer should think about this. If we want to do much better for the code. I should understand it. right? You are very good at this and show us good coding idea.

  47. Avatar
    Steve Waters Vancouver over 3 years later:

    A random act of kindness!

  48. Avatar
    find cell number over 3 years later:

    I should understand it. right? You are very good at this and show us good coding idea. find cell number

  49. Avatar
    bladeless fans over 3 years later:

    A First Look at Moq 48 good post42

  50. Avatar
    louboutin sales over 3 years later:

    A First Look at Moq 49 hoo,good article!!I like the post!133

  51. Avatar
    how to made hho generator over 3 years later:

    Same with other things we modified. We can always forget a slight thing here and there when advancing, but we always spend a good slice of time in public try out to reduce this, including individual reviews.

  52. Avatar
    Injection Mold over 3 years later:

    With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.

    For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.

Comments