模拟框架如何工作? [英] How do mock frameworks work?

查看:64
本文介绍了模拟框架如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我要编写一个模拟库,这将如何工作(换句话说,它们如何工作?")?

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 expectations so really you need to compare the expectation to what the method does at runtime, so I assume reflection (resolving types at runtime) is required.

在使用模拟对象"一词时,该对象是否被存根还是将成为具有预设期望的对象?

Also, when using the term "mock object", is the object stubbed out or would it be an object with pre-set expectations?

当我想到如何编写自己的框架/技术实现(如模拟对象)时,我意识到我真正了解(或不知道)多少,以及接下来要进行的工作:如果模拟对象是预编程以返回设定的期望值,而您不调用实际的真实对象,那么结果将不会总是相同的吗?例如:

When I think how I would write my own implementation of a framework/technique, like mock objects, I realise how much I really know (or don't know) and what I would trip up on: If the mock object is pre-programmed to return set expectations and you don't call the actual real object, then wouldn't the result always be the same? Eg:

[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs()
{
    var fake = Isolate.Fake.Instance<ClassToIsolate>();
    // MethodReturnInt will return 10 when called with arguments 3, "abc"
    Isolate.WhenCalled(()=> fake.MethodReturnInt(3,   "     abc")).WithExactArguments().WillReturn(10);
// MethodReturnInt will return 50 when called with arguments 3, "xyz"
    Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "xyz")).WithExactArguments().WillReturn(50);

     Assert.AreEqual(10, fake.MethodReturnInt(3, "abc"));
    Assert.AreEqual(50, fake.MethodReturnInt(3, "xyz"));

}

这不总是返回true吗?

Wouldn't this always return true?

推荐答案

使用模拟框架的想法是模拟依赖性,而不是测试中的实际类.对于您的示例,您的测试将始终返回true,因为实际上您只是在测试模拟框架,而不是实际的代码!

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);
}

请注意如何将模拟传递给TestClass并在其上运行方法.

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:

您要做的是使用Isolate.WhenCalled()和模拟框架创建方法MethodReturnInt.当您在Assert中调用MethodRecturnInt时,代码将运行委托() => fake.MethodReturnInt()并返回10.模拟框架有效地创建了一个看起来像这样的方法(尽管是动态的):

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;
}

比这要复杂一些,但这是一般的想法.由于除了创建2个方法之后再运行任何代码,然后对这两个方法进行断言,所以您没有测试自己的代码,因此仅测试了模拟框架.

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.

这篇关于模拟框架如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆