Development Blog

 Wednesday, March 26, 2008
« The Eleutian Guys join the CodeBetter Gu... | Main | Hi, I'm Dan »

Moq has been getting some press lately because it's the newest mock framework on the block. I think it's certainly interesting and I'll have more to say on it later, but I wanted to briefly complain about one aspect real quick.

Moq touts that it has a more simplified API when compared to something like Rhino.Mocks. The API has a single entry point which certainly aids discoverability, but I question one of the design decisions. I remember seeing someone say that Rhino had too many types of mocks and that that was confusing. Well, I don't think it has this many different Mock Behaviors:

  public enum MockBehavior
  {
    Strict, 
    Normal,
    Relaxed,
    Loose,
    Default = Normal,
  }

Why have this many? Does anyone know what they do just by looking at them? At least they're documented, but the docs are quite a mouthful:

  public enum MockBehavior
  {
    /// 
    /// Causes the mock to always throw 
    /// an exception for invocations that don't have a 
    /// corresponding expectation.
    /// 
    Strict, 
    /// 
    /// Matches the behavior of classes and interfaces 
    /// in equivalent manual mocks: abstract methods 
    /// need to have an expectation (override), as well 
    /// as all interface members. Other members (virtual 
    /// and non-virtual) can be called freely and will end up 
    /// invoking the implementation on the target type if available.
    /// 
    Normal,
    /// 
    /// Will only throw exceptions for abstract methods and 
    /// interface members which need to return a value and 
    /// don't have a corresponding expectation.
    /// 
    Relaxed,
    /// 
    /// Will never throw exceptions, returning default  
    /// values when necessary (null for reference types 
    /// or zero for value types).
    /// 
    Loose,
    /// 
    /// Default mock behavior, which equals .
    /// 
    Default = Normal,
  }

I'm of the opinion that you should only have one type of Mock, and that's what Rhino calls Dynamic and Moq calls Loose. I described why here. If I wanted to simplify mocking, I'd start here.

Wednesday, March 26, 2008 8:36:38 AM (Pacific Standard Time, UTC-08:00)
Aaron, is it possible to switch mocks between types after they've been created? This is something I've always wanted in Rhino.
Jacob
Wednesday, March 26, 2008 9:01:21 AM (Pacific Standard Time, UTC-08:00)
Hmm, I'm not really sure that I agree with you. What if a default value returned from a method doesn't really fall into what is desired runtime behavior? You could theoretically have a test pass, but only because a method was returning something like an empty string, which might not be expected at runtime. I know that this is an unlikely scenario, but wouldn't it be nice to be told when a method is now being called that we weren't originally expecting when we wrote the test?
Wednesday, March 26, 2008 9:21:58 AM (Pacific Standard Time, UTC-08:00)
Jacob,

I doubt you can, that would be strange any way, when would you switch?

Justin,

This is what red/green/refactor tdd is for. If you don't get that red, something is wrong.

I think the noise and annoyances caused by strict mocks is much more annoying than any potential benefits.
Aaron
Wednesday, March 26, 2008 9:25:28 AM (Pacific Standard Time, UTC-08:00)
All other things being equal, (which they aren't, but just for the sake of the point) the contents of that enum are pretty problematic. The semantic difference between "loose" and "relaxed" is pedantic to say the least. That strikes me as a design that hasn't been thoroughly thought through.
shawn
Comments are closed.