views:

51

answers:

2

I am trying to understand how to use Moq, however I am having some confusion about what Moq should be used for. My understanding is that mock framework are used for generating objects which would be difficult to create under normal circumstances. The examples I have seen of Moq however seem to not only create Moq object, but also provide methods for testing the objects - this would appear to remove the need for the usual Assert, etc methods we use for most unit tests.

Can somebody confirm whether I am correct in thinking that Moq replaces Assert, etc, or am I completely missing the point of Moq?

+2  A: 

A mocking framework like Moq does not completely replace the testing framework's Assert. sometimes it does, sometimes it doesn't.

Let's first distinguish between mocks and stubs. Stubs are used purely for isolation and to inject some sort of controlled behaviour into system under test (SUT).

Mocks are a superset of stubs and are able to verify whether or not something was called on a mock. In Moq, an invocation of Verify() makes stub a mock with respect to that method. Calling VerifyAll() makes all methods that were set up mocks.

The recommended approach is that you should have no more than one mock in your test. In that sense, it is similar to Assert - that you shouldn't be verifying more than one thing in a test.

Coming back to the original question. If you are performing state testing, than you would use zero or more stubs and one assert. If you are doing interaction testing, than you would use zero or more stubs and one mock. Below is an example where it might be appropriate to use both mocks and asserts to test the same service.

public interface IAccountRepository {
  decimal GetBalance(int accountId);
  void SetBalance(int accountId, decimal funds);
}

public class DepositTransaction {

  IAccountRepository m_repo;

  public DepositTransaction(IAccountRepository repo) {
    m_repo = repo;
  }

  public decimal DepositedFunds {get; private set;};

  void Deposit(int accountId, decimal funds) {
    decimal balance = m_repo.GetBalance(accountId);
    balance += funds;
    m_repo.SetBalance(balance);

    DepositedFunds += funds;
  }
}

public class DepositTest {
  [TestMethod]
  void DepositShouldSetBalance() {
    var accountMock = new Mock<IAccountRepository>();
    accountMock.Setup(a=>a.GetBalance(1)).Returns(100); //this is a stub with respect to GetBalance

    var transation = new DepositTransaction(accountMock.Object);
    transation.Deposit(1, 20);

    accountMock.Verify(a=>a.SetBalance(1, 120)); //this is a mock with respect to SetBalance
  }
  [TestMethod]
  void DepositShouldIncrementDepositedFunds() {
    var accountMock = new Mock<IAccountRepository>();
    accountMock.Setup(a=>a.GetBalance(1)).Returns(100); //this is a stub with respect to GetBalance

    var transation = new DepositTransaction(accountMock.Object);
    transation.Deposit(1, 20);
    transation.Deposit(1, 30);

    Assert.AreEqual(50, transaction.DepositedFunds);

  }
}
Igor Zevaka
Only one Mock in a test? How can you build a complicated system where each thing only has a dependency on one other thing?
arootbeer
@arootbeer: Only one thing should be a Mock as defined in his answer - the others, even if they are Objects created via a Mocking framework should be fulfilling the role/responsibility of a Stub. This is a common paradigm - see xUnit Test Patterns, which is highly recommended (and this post is in line wiht many patterns in there). Essentially this is SRP. And dont forget to upvote!
Ruben Bartelink
@Ruben - Okay, that makes sense. I'm used to BDD-style testing (specifically MSpec), where you call a method and then verify that all of the mocked methods were called. But for AAA style testing, I can see only having one stub per test.
arootbeer
@arootbeer: I use SubSpec myself (see @Johannes Rudolph's extensions of same). The comments on @Phil Haack's Subspec blog post do the BDD vs Context/Specification vs AAA in some depth. While the emphasis in BDD shifts to interaction, you should still be working towards as few assertions as possible. If you have a set of specifications which talk about the 57 side-effects an action is going to have on the system, some of those will be redundant, incidental or overlapping. So for me, even in that context, @Igor Zevaka's central thesis holds.
Ruben Bartelink
(I play fast and loose with the subtle distinctions between the flavors in my answer - my aim is to emphasise the core point, which is that you need SRP in your tests/specs, no matter what approach/school you're from). Recent excellent topical video/mp3: http://www.infoq.com/presentations/Building-Good-Habits
Ruben Bartelink
@Ruben - for the most part, I find myself using one or two mocks as dependencies for any given class. However, there's almost always one or a few classes in a project that have the responsibility of doing something with all of the other classes, which is where the MSpec/BDD style of testing really shines. This class doesn't really have side effects - the point of it is to make other things cause something specific to happen. So being able to test that "On this path, these 6 things happened, and these 4 did not" is crucial. cont...
arootbeer
The one distinction I would make is that MSpec calls each `It` a test, which arguably means that each test (as they were intended to be written, at any rate :) is asserting exactly one thing.
arootbeer
SubSpec does pretty much exactly the same thing - you break stuff into Assert/Observation sections, and rarely have more than one Assertion on any path. However, there's a big difference between 5 separate Observations/Assertions and having a massive context with lots of setup, lots of Mocks and lots of coincidences - you get brittle tests and you spend a lot of time dealing with change as your tests are not focused a la SRP. But I think in general we're in the same chapter, if not on the exact same page :D
Ruben Bartelink
@Ruben - I'll agree to agree with you that we're in agreement.
arootbeer
+1  A: 

+1 on the Q and the other A...

(restating Igor's very complete answer) A Mocking library is just a tool use within a test/spec - sometimes fulfilling the role of a stub or a mock.

Record/replay based mocking can often replace the role of Asserts in your tests. This style has been deemphasized recently in RhinoMocks (I believe 4.0 was going to shunt it off to the side), and has been actively discouraged in Moq for quite some time. I believe this is what has got you asking the question.

You should be optimising your tests to:

  • Be readable for you, maintenance programmers, and pretty much anyone that's ever going to have to debug or extract info from your test code
  • Assert as few things as possible
  • Not overlap with other tests
  • Not be brittle - tests shouldn't be breaking for incidental reasons when you change something only tangentially related to your test. In the context of Moqing and mocking, this means veering away from Strict mocks in most cases
  • Do as little work as possible to prove their point
  • Have clear separation of Arrange/Context, Act and Assert sections

The final point here is the critical one - you want one bit where you're doing Checks, and it should be the final Assert one. Sometimes this can mean that you can even end up doing a Setup a call in Moq in the Arrange/Context phase and then Verify that it got used in the Assert phase with code that looks like duplication.

Ruben Bartelink