为什么模拟测试框架会有所帮助? [英] Why are mocking test frameworks helpful?

查看:80
本文介绍了为什么模拟测试框架会有所帮助?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎我看过的所有Mockito示例都伪造"了他们正在测试的对象的行为.

It seems like all of the Mockito examples I have looked at, "fake" the behavior of the object they are testing.

如果我的对象具有方法:

If I have an object that has a the method:

public int add(int a, int b) {return a+b}

我只是使用JUnit断言传入的两个整数是否会导致正确的输出.

I would simply use JUnit to assert whether two integers passed in would result in the correct output.

利用我在Mockito中看到的所有示例,人们正在做when.Object.add(2,3).thenReturn(5)之类的事情.如果您要做的就是告诉对象如何在测试端而不是对象端起作用,那么使用此测试框架有什么意义呢?

With all of the examples I've seen with Mockito, people are doing things like when.Object.add(2,3).thenReturn(5). What's the point of using this testing framework, if all you're doing is telling the object how to act on the test side, rather than the object side?

推荐答案

模拟框架非常适合通过模拟系统的依赖项来测试系统.如果要测试add,则不会使用模拟框架来模拟或存根add.让我们进一步说明:

Mocking frameworks are good for testing a system by mocking that system's dependencies; you wouldn't use a mocking framework to mock or stub add if you are testing add. Let's break this out a bit further:

模拟框架对在上面测试add方法的 不利.除了非常稳定且经过充分测试的JVM和JRE,没有其他依赖项.

A mocking framework is not good for testing your add method above. There are no dependencies other than the very stable and extremely-well-tested JVM and JRE.

public int add(int a, int b) {return a+b}

但是,如果要与这样的另一个对象进行交互,则最好测试您的添加方法 :

However, it might be good for testing your add method if it were to interact with another object like this:

public int add(int a, int b, AdditionLogger additionLogger) {
    int total = a + b;
    additionLogger.log(a, b, total);
    return total;
}

如果尚未编写AdditionLogger,或者编写它是为了与真实服务器或其他外部进程通信,那么模拟框架绝对有用:它将帮助您提出伪造的AdditionLogger实现,从而可以测试您的真实方法与之的交互.

If AdditionLogger isn't written yet, or if it's written to communicate with a real server or other external process, then a mocking framework would absolutely be useful: it would help you come up with a fake implementation of AdditionLogger so you could test your real method's interactions with it.

@Test public void yourTest() {
    assertEquals(5, yourObject.add(2, 3, mockAdditionLogger));
    verify(mockAdditionLogger).log(2, 3, 5);
}

测试add的使用者

巧合的是,模拟框架也不太可能对测试上述方法的使用者有用.毕竟,对add的调用没有什么特别危险的,因此,假设存在add,您可以在外部测试中调用真实的. 2 + 3将始终等于5,并且您的计算没有任何副作用,因此通过模拟或验证几乎无济于事.

Testing add's consumers

Coincidentally, a mocking framework is also unlikely to be good for testing consumers of your method above. After all, there is nothing particularly dangerous about a call to add, so assuming it exists you can probably call the real one in an external test. 2 + 3 will always equal 5, and there are no side effects from your calculation, so there's very little to be gained by mocking or verifying.

但是,让我们为您的对象提供另一个方法,该方法将两个数字相加并带有一点随机噪声:

However, let's give your object another method that adds two numbers with a little bit of random noise:

public int addWithNoise(int a, int b) {
    int offset = new Random().nextInt(11) - 5;  // range: [-5, 5]
    int total = a + b + offset;
    return total;
}

使用此方法,您可能很难针对此方法编写健壮的assert型测试;毕竟,结果将是随机的!相反,为了使assert样式的测试更容易,也许我们可以将addWithNoise存根以使其中的一些更可预测.

With this, it may be very hard for you to write a robust assert-style test against this method; after all, the result is going to be somewhat random! Instead, to make an assert-style test easier, maybe we can stub out addWithNoise to make some of this more predictable.

@Test public void yourTest() {
    when(yourObjectMock.addWithNoise(2, 3)).thenReturn(6);
    // You're not asserting/verifying the action you stub, you're making the dependency
    // *fast and reliable* so you can check the logic of *the real method you're testing*.
    assertEquals(600, systemUnderTestThatConsumesYourObject.doThing(yourObjectMock));
}

总结

与诸如add之类的知名操作或诸如List之类的知名接口进行交互时,更容易解释模拟和模拟语法,但是这些示例通常不是需要模拟的现实情况.请记住,当您不能使用真实对象时,模拟仅对模拟被测系统周围的依赖项真正有用.

In summary

It can be easier to explain mocking and mock syntax when interacting with well-known operations like add or well-known interfaces like List, but those examples are not usually realistic cases where mocks are needed. Remember that mocking is only really useful for simulating the dependencies around your system-under-test when you can't use real ones.

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

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