c# 方法存根_模拟,伪造和存根C ++

c# 方法存根

Here’s a look at a new approach we’re trying for doing unit testing in a huge C++ legacy codebase that is largely hostile to testing.

这是我们正在尝试在庞大的C ++遗留代码库中进行单元测试的一种新方法,该代码库在很大程度上不利于测试。

We think a lot about testing. Both because we want to feel more comfortable changing things, and because we realize that many, many developers depend on Unity being stable and reliable. And that’s something we want to continuously get better at.

我们对测试进行了很多思考。 既因为我们想对事情进行更改感到更自在,又因为我们意识到许多开发人员都依赖Unity稳定可靠。 这就是我们想要不断变得更好的地方。

We have previously blogged about how we do high-level testing from C#, but over time we have come to realize that we also need much more low-level, much faster, and much more fine-grained tests. The thing is, though, that our C++ codebase is rather hostile to any such test. Testing a huge C++ codebase with lots of legacy code is tough.

我们 之前曾在博客中 介绍过如何使用C#进行高级测试,但是随着时间的流逝,我们逐渐意识到,我们还需要更多的低级,更快,更细粒度的测试。 事实是,我们的C ++代码库对任何此类测试都相当敌对。 用大量遗留代码测试巨大的C ++代码库非常困难。

But… we’ve now made it a little easier.

但是……我们现在使它变得容易一些。

After looking around and realizing that no-one quite solves the problem the way we need to (what TypeMock does comes closest but it’s Windows-only so not of much use to us), we sat down and pondered what we could do. Obviously, we can’t rewrite our whole codebase for the sake of tests. Whatever we were to come up with would have to work with where we are and with how we write C++ code.

环顾四周并意识到没有人能以所需的方式解决问题( TypeMock 确实最接近它,但它仅适用于Windows,因此对我们没有太大用处),我们坐下来思考我们可以做什么。 显然,为了测试,我们不能重写整个代码库。 无论我们要想出什么,都必须与我们所处的位置以及我们编写C ++代码的方式一起工作。

劫持... (Hijacking…)

This made us realize that the one thing we want is the ability to hijack any function anywhere in our tests. Take it over, mock it, fake it, stub it, rule it. We’re okay with function X calling function Y directly, as long as tests can hijack the thing and turn function Y into whatever they want.

这使我们意识到,我们想要的一件事是能够劫持测试中任何地方的任何功能。 接管,模拟,伪造,存根,统治它。 只要测试可以劫持事物并将函数Y转换为所需的值,我们就可以直接使用函数X调用函数Y。

So we thought “code patching!” Turns out we had just developed this nifty framework to do live code patching for the sake of profiling. But the problem is many platforms don’t allow runtime code patching, so that rules out that option.

因此我们认为“代码修补!” 事实证明,我们刚刚开发了这个漂亮的框架来进行性能分析以进行概要分析。 但是问题是许多平台不允许运行时代码修补,因此排除了该选项。

……在编译时…… (… At Compile-Time …)

So then we thought “no problem, we patch at compile time!” Tricky! Some guys have done it, like the Bullseye guys whose tech we use for C++ code coverage monitoring, but it’s still really quite involved. And we have many different compilers across a variety of platforms so… no. And our builds are already quite complicated.  So that one’s out as well.

因此,我们想到了“没问题,我们在编译时打补丁!” 整rick 有些人已经做到了,例如 Bullseye的 人,我们将其技术用于C ++代码覆盖率监视,但它确实涉及很多。 而且我们在各种平台上都有许多不同的编译器,所以……不。 而且我们的构建已经相当复杂。 这样也可以出来。

…带宏 (… With Macros)

With C++, if you have nothing else, you always have macros and templates. So I sat down, got my < and > keys ready and wrote us some templates sprinkled with some macro bits.

使用C ++,如果您一无所有,那么您总会拥有宏和模板。 所以我坐下,准备好<和>键,并写了一些带有一些宏位的模板给我们。

The proposition is actually pretty simple: once you have a mechanism to hook into any function, you can build a whole framework on top that reprograms those functions for whatever is needed in tests.

这个主张实际上很简单:一旦有了一种机制可以挂接到任何函数上,就可以在顶部构建一个完整的框架,以便为测试中需要的功能重新编程这些函数。

So first step: hooks. Goes like this:

所以第一步:钩子。 像这样:

Screen Shot 2015-11-24 at 11.02.19

It’s simple. Does nothing by default (and actually compiles to nothing in builds we ship) but when tests grab the hook, it turns into magic. There’s a bit of intrusiveness but it’s very modest.

这很简单。 默认情况下不执行任何操作(实际上在我们交付的版本中不执行任何操作),但是当测试抓住问题时,它将变成魔术。 有一些侵入性,但非常适度。

Next step is to make the hook go live during a test:

下一步是使钩子在测试期间生效:

Screen Shot 2015-11-24 at 11.02.37

This will look up the hook based on the function signature and then grab the hook for as long as the fake is in scope. 

这将根据函数签名查找该钩子,然后只要该伪造物在范围内,就抓住该钩子。

So finally, we can program the hook:

最后,我们可以对钩子进行编程:

Screen Shot 2015-11-24 at 11.02.51

From here, you can do all the usual mocking like redirecting the call to your own function, observing arguments and return values, and running the original function in a controlled way. And it’s straightforward to support instance methods in addition to free functions. In fact, the system makes it easy to even replace entire classes.

在这里,您可以进行所有常见的模拟操作,例如将调用重定向到您自己的函数,观察参数和返回值以及以受控方式运行原始函数。 除了免费功能之外,直接支持实例方法也很简单。 实际上,该系统甚至可以轻松替换整个类。

Screen Shot 2015-11-24 at 11.03.03

结论 (Conclusion)

We have yet to see the full impact of this new approach over time, but we’ve already found that there are many tests that we can now write that we couldn’t write before. While we will not let up on functional testing, we hope that with a high-speed, comprehensive, and granular native test suite we further add to the robustness of the Unity core.

随着时间的推移,我们还没有看到这种新方法的全部影响,但是我们已经发现,现在可以编写许多以前无法编写的测试。 尽管我们不会放弃功能测试,但我们希望借助高速,全面,细粒度的本机测试套件,我们可以进一步提高Unity内核的健壮性。

翻译自: https://blogs.unity3d.com/2015/11/25/mocking-faking-and-stubbing-c/

c# 方法存根

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值