单元测试功能有副作用吗?

发布于 2024-09-16 01:07:14 字数 661 浏览 6 评论 0原文

假设您正在编写一个函数来检查是否通过适当的 URL 访问了某个页面。该页面有一个“规范”存根 - 例如,虽然可以通过 stackoverflow.com/questions/123 访问页面,但我们更愿意(出于 SEO 原因)将其重定向到 stackoverflow.com/questions/123/how-do -i-move-the-turtle-in-logo - 实际的重定向安全地包含在它自己的方法中(例如,redirectPage($url)),但是如何正确测试调用它的函数?

例如,采用以下函数:

function checkStub($questionId, $baseUrl, $stub) {
  canonicalStub = model->getStub($questionId);
  if ($stub != $canonicalStub) {
    redirectPage($baseUrl . $canonicalStub);
  }
}

如果要对 checkStub() 函数进行单元测试,重定向不会妨碍吗?

这是一个更大问题的一部分,其中某些功能似乎变得太大并且离开了单元测试领域并进入了集成测试领域。我的大脑立即想到路由器和控制器存在此类问题,因为测试它们必然会导致页面的生成,而不仅仅是局限于它们自己的功能。

我只是在单元测试中失败了吗?

Let's say you're writing a function to check if a page was reached by the appropriate URL. The page has a "canonical" stub - for example, while a page could be reached at stackoverflow.com/questions/123, we would prefer (for SEO reasons) to redirect it to stackoverflow.com/questions/123/how-do-i-move-the-turtle-in-logo - and the actual redirect is safely contained in its own method (eg. redirectPage($url)), but how do you properly test the function which calls it?

For example, take the following function:

function checkStub($questionId, $baseUrl, $stub) {
  canonicalStub = model->getStub($questionId);
  if ($stub != $canonicalStub) {
    redirectPage($baseUrl . $canonicalStub);
  }
}

If you were to unit test the checkStub() function, wouldn't the redirect get in the way?

This is part of a larger problem where certain functions seem to get too big and leave the realm of unit testing and into the world of integration testing. My mind immediately thinks of routers and controllers as having these sorts of problems, as testing them necessarily leads to the generation of pages rather than being confined to just their own function.

Do I just fail at unit testing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

围归者 2024-09-23 01:07:14

你说...

这是一个更大问题的一部分,其中某些功能似乎变得太大并离开单元测试领域并进入集成测试世界

我认为这就是为什么单元测试(1)很难并且(2)导致代码不正确的原因不会因自身重量而崩溃。您必须小心翼翼地打破所有依赖项,否则您最终会遇到单元测试==集成测试。

在您的示例中,您将注入重定向器作为依赖项。你使用模拟、替身或间谍。然后你按照@atk 的安排进行测试。有时这是不值得的。更多时候,它会迫使您编写更好的代码。没有 IOC 容器就很难做到这一点。

You say...

This is part of a larger problem where certain functions seem to get too big and leave the realm of unit testing and into the world of integration testing

I think this is why unit testing is (1) hard and (2) leads to code that doesn't crumble under its own weight. You have to be meticulous about breaking all of your dependencies or you end up with unit tests == integration tests.

In your example, you would inject a redirector as a dependency. You use a mock, double or spy. Then you do the tests as @atk lays out. Sometimes it's not worth it. More often it forces you to write better code. And it's hard to do without an IOC container.

难如初 2024-09-23 01:07:14

这是一个老问题,但我认为这个答案是相关的。 @Rob 指出您将注入一个重定向器作为依赖项 - 当然,这是可行的。然而,你的问题是你没有很好地分离关注点。

您需要使函数尽可能原子化,然后使用您创建的粒度函数组合更大的功能。你这样写:

function checkStub($questionId, $baseUrl, $stub) {
  canonicalStub = model->getStub($questionId);
  if ($stub != $canonicalStub) {
    redirectPage($baseUrl . $canonicalStub);
  }
}

我会这样写:

  function checkStubEquality($stub1, $stub2) {
    return $stub1 == $stub2;
  }

  canonicalStub = model->getStub($questionId);
  if (!checkStubEquality(canonicalStub, $stub)) redirectPage($baseUrl . $canonicalStub);

This is an old question, but I think this answer is relevant. @Rob states that you would inject a redirector as a dependency - and sure, this works. However, your problem is that you don't have a good separation of concerns.

You need to make your functions as atomic as possible, and then compose larger functionality using the granular functions you've created. You wrote this:

function checkStub($questionId, $baseUrl, $stub) {
  canonicalStub = model->getStub($questionId);
  if ($stub != $canonicalStub) {
    redirectPage($baseUrl . $canonicalStub);
  }
}

I'd write this:

  function checkStubEquality($stub1, $stub2) {
    return $stub1 == $stub2;
  }

  canonicalStub = model->getStub($questionId);
  if (!checkStubEquality(canonicalStub, $stub)) redirectPage($baseUrl . $canonicalStub);
稳稳的幸福 2024-09-23 01:07:14

听起来你只是有另一个测试用例。您需要检查该存根是否被正确识别为具有正面和负面测试的存根,并且需要检查您重定向到的页面是否正确。

或者我完全误解了这个问题?

It sounds like you just have another test case. You need to check that the stub is identified correctly as a stub with both positive and negative testing, and you need to check that the page to which you are redirected is correct.

Or do I totally misunderstand the question?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文