English 中文(简体)
我何时应该 mo?
原标题:When should I mock?

我对 mo和面包物体有基本了解,但我不敢肯定,我会感觉到何时或何地使用 mo,特别是因为这将适用于这种情况:

最佳回答

单位测试应通过单一方法测试单一代码。 如果在这种方法之外使用这种方法,转而使用另一物体,并再次使用,则有依赖。

当你测试该法典与实际依赖性之间的关系时,你不是单位检测;你是一体化测试。 虽然这是好的,也是必要的,但它是单体检测。

如果你的依赖是假的,那么你的考验可能会以这种方式受到影响,以换取一种虚假的积极性。 例如,你可能会将依赖性推倒出乎意料的,而依赖性可能不会因为有文件记载而消失。 你的检验没有遇到应有的否定性例外,也没有检验通行证。

而且,你可能发现,如果不可能,很难可靠地获得依赖物体,以在试验期间完全恢复你想要的东西。 这包括在试验中放弃预期的例外。

一辆ck车取代了这种依赖。 你寄希望于对依赖物体的电话,设定了它应给你以的准确回归价值,以检验你想要的检验,以及(或)什么例外,以便你能够测试你的例外处理法。 这样,你就可以方便地测试有关单位。

TL;DR:Mock 每一次依赖你的单位试验都触及。

问题回答

当你想在受测试的某一类别和某个特定接口之间测试互动时,磁物体是有用的。

例如,我们要测试以下方法:send Invitations(mailServermailServer) callsmailServer.createMessage(,准确无误地一次;mailerver.sendMessage(m),而且没有其他方法在接口上发出。 这就是我们能够使用模拟物体的时候。

使用模拟物体,而不是通过真实的<代码> 邮件ServerImpl,或测试<代码> 试验邮件Server<> 代码”,我们可以通过模拟执行<密码>。 在我们通过一个 mo形码(/code>之前,我们“train”,这样它就知道需要什么样的方法,以及返回的价值。 最后, mo子声称,所有预期方法都按预期使用。

这在理论上是好的,但也有一些下滑。

Mock shortcomings

如果你有一个模拟框架,你就被诱惑使用模拟物体every time,你需要通过试样与舱面连接。 这样,你就可以结束<斯特隆>的交流,即使没有必要。 不幸的是,对互动的不必要(偶然)测试是坏的,因为当时,你重新测试一项具体要求以某种方式执行,而不是因为执行产生必要的结果。

这里就是一个假编码的例子。 让我们ve立一个<条码>。

// the correct way of testing
testSort() {
    testList = [1, 7, 3, 8, 2] 
    MySorter.sort(testList)

    assert testList equals [1, 2, 3, 7, 8]
}


// incorrect, testing implementation
testSort() {
    testList = [1, 7, 3, 8, 2] 
    MySorter.sort(testList)

    assert that compare(1, 2) was called once 
    assert that compare(1, 3) was not called 
    assert that compare(2, 3) was called once 
    ....
}

(在这个例子中,我们假设,它不是一种特殊的分类算法,例如快速算法,我们希望测试;在这种情况下,后一种检验实际上有效。)

在这样一个极端的例子中,它显然说明为什么后者是错误的。 当我们改变<代码>MySorter的实施时,第一种检验方法非常有助于确保我们仍然正确行事,这是整个测试点,使我们能够安全地改变守则。 另一方面,后一项检验标准always断裂,而且它非常有害;它阻碍重温。

Mocks as stubs

磁场框架往往允许使用较少的严格做法,在这种情况下,我们不必确切地说明应当使用多少方法和预期的参数;它们允许制造用作stubs

让我们使用一种方法<代码>后邀请(PdfFormatter pdfFormatter, 邮报ServermailServer),我们希望测试。 <代码>PdfFormatter物体可用于制作邀请书。 试验:

testInvitations() {
   // train as stub
   pdfFormatter = create mock of PdfFormatter
   let pdfFormatter.getCanvasWidth() returns 100
   let pdfFormatter.getCanvasHeight() returns 300
   let pdfFormatter.addText(x, y, text) returns true 
   let pdfFormatter.drawLine(line) does nothing

   // train as mock
   mailServer = create mock of MailServer
   expect mailServer.sendMail() called exactly once

   // do the test
   sendInvitations(pdfFormatter, mailServer)

   assert that all pdfFormatter expectations are met
   assert that all mailServer expectations are met
}

在这个例子中,我们并不真正关心<代码>。 PdfFormatter Object, so we only training it to quietly receive any calls and re some sensible canated Return Value for all methods send Invitation ( when are to calls at this point. 我们如何确切提出这一培训方法清单? 我们只是进行了试验,在试验通过之前不断补充方法。 我们发出这样的通知,即我们训练了 st,以回应一种方法,而没有它为什么需要称之为这种方法,我们只是增加了试验所抱怨的一切。 我们高兴的是,测试通行证。

但后来,当我们修改<条码>后邀请书()或使用<条码>后邀请书()的其他一些类别,以创造更多的活力? 我们的测试突然失败,因为现在需要采用更多的<代码>PdfFormatter的方法,而且我们没有培训我们期望这些方法。 通常,它不仅是一种在类似情况下失败的测试,而且还会受到直接或间接使用<代码>后邀请(方法的任何测试。 我们必须通过增加更多的培训来确定所有这些试验。 我们还注意到,我们无法消除不再需要的方法,因为我们不知道其中哪些办法不需要。 同样,这妨碍了令人振奋。

而且,试验的可读性也受到可怕的影响,在那里,由于我们想要,但因为我们不得不这样做,我们没有书写文字;它不是我们谁想要这个法典。 使用模拟物体的试验非常复杂,往往难以阅读。 测试应有助于读者了解,如何使用测试中的类别,因此,这些类别应当简单明了。 如果他们不能读懂,任何人都不会维持;事实上,删除他们比保持他们更容易。

如何确定这一点? 容易:

  • Try using real classes instead of mocks whenever possible. Use the real PdfFormatterImpl. If it s not possible, change the real classes to make it possible. Not being able to use a class in tests usually points to some problems with the class. Fixing the problems is a win-win situation - you fixed the class and you have a simpler test. On the other hand, not fixing it and using mocks is a no-win situation - you didn t fix the real class and you have more complex, less readable tests that hinder further refactorings.
  • Try creating a simple test implementation of the interface instead of mocking it in each test, and use this test class in all your tests. Create TestPdfFormatter that does nothing. That way you can change it once for all tests and your tests are not cluttered with lengthy setups where you train your stubs.

几乎所有物体都有其使用,但如不谨慎使用,they往往鼓励不良做法、测试执行细节、阻碍重构和难以阅读和难以维持

关于摩擦缺点的更多详情,另见。 ock:短程和使用案例

th:

如果你测试功能需要一个复杂的物体作为参数,那么简单明了这个物体(例如,如果它试图建立TCP联系),则会使用一个模拟器。

当你依赖某一部法典时,你会试图测试需要“合理”的物体。

例如,当你试图在你的法典单位中测试某种逻辑时,你需要从另一个物体那里获得某种东西,而从这种依赖状态中回归的东西可能会影响到你试图测试的东西—— object。

可在here上查阅有关该主题的大图。

  1. Mock the interfaces that you don t own. When your code calls out to a third-party service, you should mock that service. This allows your test to exercise the calling code (which you do own) without being coupled to the performance characteristics of other services. It also allows you to separate issues in your application from issues in other applications. For example, you might use a tool like WireMock to represent http-based services; and use an in-memory data store to represent an actual database.
  2. Mock the services that would cause collisions among your tests. Avoid writing individual tests that are required to run sequentially, by mocking the common services where collisions would occur. This is another reason for an in-memory data store that can spin up instances in parallel: the effects of multiple tests can collide in a single database, making the output inconsistent and unpredictable. Strive for tests that can run in parallel, even if you don t actually run them in parallel today. It gives you the option to drastically improve performance in the future with a simple configuration change.
  3. Mock the services whose real implementations would cause your tests to run unacceptably slowly. The slower the tests, the less often they will be run. The less often the tests run, the less feedback the developers receive. The less feedback the developers receive, the higher the risk of poor code quality.
  4. Avoid mocking your own internal services. Mocking your own services couples your tests to the current implementation details of those services (including class names and method signatures, etc.). You want to be able to make minor refactorings to your codebase (such as renaming classes and methods) without breaking tests. If refactoring is easy, developers will be encouraged to do more of it, which will increase the quality of the code over time.
  5. Bonus mocking advice: mock the interfaces that are unstable or unknown. Avoid constantly rewriting tests by mocking interfaces that are under active development or even hypothetical. Mocking can facilitate a proof-of-concept.

简言之,如果你能够迅速、一致地同时进行测试,那么你就重新做了ck弄的良好工作。 如果你的编码基础能够支持不中断这些试验的微小因素,那么你就重新做了大量模拟工作。 这可能意味着你只做很少的 mo笑!





相关问题
run unit tests and coverage in certain python structure

I have some funny noob problem. I try to run unit tests from commandline: H:PROpyEstimator>python src estpython est_power_estimator.py Traceback (most recent call last): File "src est...

How to unit-test an enterprise symfony project?

I´m working on a huge project at my work. We have about 200 database tables, accordingly a huge number of Models, Actions and so on. How should I begin to write tests for this? My biggest problem ...

Code Coverage Tools & Visual Studio 2008 Pro

Just wondering what people are using for code coverage tools when using MS Visual Studio 2008 Pro. We are using the built-in MS test project and unit testing tool (the one that come pre-installed ...

Unit testing. File structure

I have a C++ legacy codebase with 10-15 applications, all sharing several components. While setting up unittests for both shared components and for applications themselves, I was wondering if there ...

Unit Testing .NET 3.5 projects using MStest in VS2010

There s a bug/feature in Visual Studio 2010 where you can t create a unit test project with the 2.0 CLR. https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=483891&wa=...

Unit Test for Exceptions Message

Is there a simple (Attribute-driven) way to have the following test fail on the message of the exception. [TestMethod()] [ExpectedException(typeof(ArgumentException))] public void ExceptionTestTest() ...

热门标签