简体   繁体   English

如何对有很多重叠的代码进行单元测试?

[英]How should I unit test code with a lot of overlap?

I'm relatively new to unit testing. 我是单元测试的新手。 I'm writing a small JavaScript library where I've prioritized a friendly API, which leads to some method overlap for the sake of convenient usage. 我正在编写一个小型JavaScript库,在该库中我对友好的API进行了优先级排序,为了方便使用,该方法导致某些方法重叠。

As a simple, hypothetical example, consider the following: 作为一个简单的假设示例,请考虑以下内容:

var BasicMath = function() {};

BasicMath.prototype.multiply = function(numA, numB) {
  return numA * numB;
};

BasicMath.prototype.square = function(num) {
  return this.multiply(num, num);
};

How should I unit test this code? 我应该如何对该代码进行单元测试?

Note that .square() is just a convenience method that does nothing but pass along its argument twice to .multiply() . 请注意, .square()只是一种便捷方法,除了将其参数两次传递给.multiply() ,什么也不做。

With that in mind, should I: 考虑到这一点,我应该:

  • write similar (or even identical) unit tests for both methods? 为这两种方法编写相似(甚至相同)的单元测试?
  • test that .square() calls .multiply() with certain arguments? 测试.square()调用.multiply()与某些参数? (My understanding is that this is bad practice, since it relies too heavily on the method's implementation details.) (我的理解是,这是一种不好的做法,因为它过于依赖该方法的实现细节。)
  • not test .square() at all, since it's essentially redundant to .multiply() ? 根本不测试.square() ,因为它对.multiply()本质上是多余的?
  • test only the more general aspects of .square() (like argument type, quantity, etc.), to avoid redundancy with .multiply() ? 仅测试.square()的更一般方面(例如参数类型,数量等),以避免使用.multiply()冗余处理?

Or, some other approach? 还是其他方法?

Please keep in mind that the code above is just a contrived example - I'm asking a more general question about how to unit test methods with overlapping/redundant functionality. 请记住,上面的代码只是一个虚构的示例-我在问一个更笼统的问题,关于如何对具有重叠/冗余功能的测试方法进行单元化。

Example using jasmine and sinon: 使用茉莉花和西农的例子:

test Multiply like any other method: 像其他任何方法一样测试乘:

it('multiplies two numbers', function () {
    math = new BasicMath();
    expect(math.multiply(2,3)).toBe(6);
}

with square , you want to test that it calls multiply passing as both arguments the value of num and returns the result returned by multiply without performing any other logic: square ,你要测试它调用multiply传递的两个参数的值num并返回返回的结果multiply而不执行任何其他逻辑:

it('squares a number', function () {
    math = new BasicMath();
    math.multiply = sinon.stub();
    math.multiply.withArgs(2,2).returns(4);

    expect(math.square(2)).toBe(4);
}

what you do with this is create a reproducible environment using a stub, which will always expect the call to be with two identical args (in this case 2 and 2), which tests that square is sending num and num (and not num and num + 1 for example), and returns the result of the call to multiply (you could tell the stub to return 'banana' and check for 'banana' , what's important is square returns whatever multiply returns) 您要做的是使用存根创建可重现的环境,该存根将始终期望该调用具有两个相同的args(在本例中为2和2),这将测试square发送的是numnum (而不是numnum + 1例如num + 1 ),并返回乘以调用的结果(您可以告诉存根返回'banana'并检查'banana' ,重要的是, square multiply返回)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM