How do mock frameworks work?

前端 未结 4 931
再見小時候
再見小時候 2021-01-04 18:18

If I was to write a mocking library, how would this work (in other words, how do \"they work?)?

One of the things which I wonder is that you are always setting expec

相关标签:
4条回答
  • 2021-01-04 18:53

    Yes, it will always return true. Mock objects should be used when the class under test requires another class implementation that you don't want to involve in the test run. This is most useful when it's a class that uses interfaces with multiple implementations, or there are complex/expensive/external services that you don't want to set up.

    In the above code, you're mocking the class that you're "testing".

    Another way of thinking about it is that the mock behaviours you record are black-box (implementation) assertions, where Assert.* are white-box (api) assertions.

    0 讨论(0)
  • 2021-01-04 18:58

    One way to look at how mock system work is just look at times when you need an object but you don't want to use the real class but instead want it to give you some specific kind of data that it wouldn't (or won't do so reliably). So if you see:

    Assert.IsTrue(myLogic.IsNoon(time))
    

    you can see how the assert would want the time object to always be noon. . . well you can't do that with a real object reliably. So you need a stand-in. You can make a fake class just for the test, but that's sort of heavy. Mock frameworks are a shortcut.

    0 讨论(0)
  • 2021-01-04 19:10

    You have the right idea. You will often find that they have a couple of modes of operation. If you're worried about your method not getting called or it not getting called in the right order there is quite often a 'strict' mode that causes the mock framework to throw an exception if the method isn't called by the end of the test, or is called with the wrong parameters etc.

    Most of the frameworks have thought of those sorts of issues so you just need to find out how to configure it for your scenario.

    0 讨论(0)
  • 2021-01-04 19:17

    The idea with mocking frameworks is to mock out dependencies, and not the actual classes under test. For your example, your test will always return true, because really you're only testing the mocking framework and not your actual code!

    A real world mock would look more like this:

    [TestMethod, Isolated]
    public void FakeReturnValueByMethodArgs() {
        var fake = Isolate.Fake.Instance<DependencyClass>();
        // MethodReturnInt will return 10 when called with arguments 3, "abc"
        Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "abc")).WithExactArguments().WillReturn(10);
    
        var testClass = new TestClass(fake);
        testClass.RunMethod();
    
        // Verify that the setup methods were execute in RunMethod()
        // Not familiar with TypeMock's actual method to do this...
        IsolatorExtensions.VerifyInstanceWasCalled(fake);  
    
        // Or assert on values
        Assert.AreEqual(10, testClass.AProperty);
    }
    

    Notice how the mock is passed into the TestClass and a method run on it.

    You can read The Purpose of Mocking to get a better idea of how mocking works.


    Update: Explanation why you're testing only the mocking framework:

    What you've done is create a method MethodReturnInt with the mocking framework using Isolate.WhenCalled(). When you call MethodRecturnInt in the Assert, the code will run the delegate () => fake.MethodReturnInt() and return 10. The mocking framework is effectively creating a method (albeit dynamically) that would look something like this:

    public void MethodReturnInt(int value, string value2) {
        Assert.Equal(3, value);
        Assert.Equal("abc", value2);
        return 10;
    }
    

    It's a bit more complicated than that, but this is the general idea. Since you never run any code other than the creation of 2 methods and then asserts on those two methods, you're not testing your own code and therefore only testing the mocking framework.

    0 讨论(0)
提交回复
热议问题