我有以下实现,
public interface IMath {
double Add(double a, double b);
double Subtract(double a, double b);
double Divide(double a, double b);
double Multiply(double a, double b);
double Factorial(int a);
}
public class CMath: IMath {
public double Add(double a, double b) {
return a + b;
}
public double Subtract(double a, double b) {
return a - b;
}
public double Multiply(double a, double b) {
return a * b;
}
public double Divide(double a, double b) {
if (b == 0)
throw new DivideByZeroException();
return a / b;
}
public double Factorial(int a) {
double factorial = 1.0;
for (int i = 1; i <= a; i++)
factorial = Multiply(factorial, i);
return factorial;
}
}
如果计算 n 的因子,我如何测试Multiply()
被称为 n 次?
我正在使用NUnit 3和Moq。以下是我已经写过的测试,
[TestFixture]
public class CMathTests {
CMath mathObj;
[SetUp]
public void Setup() {
mathObj = new CMath();
}
[Test]
public void Add_Numbers9and5_Expected14() {
Assert.AreEqual(14, mathObj.Add(9, 5));
}
[Test]
public void Subtract_5From9_Expected4() {
Assert.AreEqual(4, mathObj.Subtract(9, 5));
}
[Test]
public void Multiply_5by9_Expected45() {
Assert.AreEqual(45, mathObj.Multiply(5, 9));
}
[Test]
public void When80isDividedby16_ResultIs5() {
Assert.AreEqual(5, mathObj.Divide(80, 16));
}
[Test]
public void When5isDividedBy0_ExceptionIsThrown() {
Assert.That(() => mathObj.Divide(1, 0),
Throws.Exception.TypeOf<DivideByZeroException>());
}
[Test]
public void Factorial_Of4_ShouldReturn24() {
Assert.That(mathObj.Factorial(4), Is.EqualTo(24));
}
[Test]
public void Factorial_Of4_CallsMultiply4Times() {
}
}
我使用Moq相当新,所以我现在还不太明白。
答案 0 :(得分:6)
你需要分离模拟部分和测试部分,因为Moq是关于消除依赖关系,而你的CMath类没有它们!
但基本上你不需要测试,Multiply被称为4次 - 它的内部实现。测试结果:))
创建Separate Factorial类,以便乘法将在单独的界面中。
public interface IMath {
double Add(double a, double b);
double Subtract(double a, double b);
double Divide(double a, double b);
double Multiply(double a, double b);
}
public interface IFactorial {
double Factorial(int a, IMath math);
}
在你的测试中,你可以创建Mock of IMath
[Test]
public void Factorial_Of4_CallsMultiply4Times()
{
var mathMock = new Mock<IMath>();
var factorial = new Factorial();
factorial.Factorial(4, mathMock.Object);
mathMock.Verify(x => x.Multiply(It.IsAny<double>()), Times.Exactly(4));
}
public double Factorial(int a, Func<double,double,double> multiply = null)
{
multiply = multiply ?? CMath.Multiply;
double factorial = 1.0;
for (int i = 1; i <= a; i++)
factorial = multiply(factorial, i);
return factorial;
}
[Test]
public void Factorial_Of4_CallsMultiply4Times()
{
var mathMock = new Mock<IMath>();
var math = new CMath();
math.Factorial(4, mathMock.Object.Multiply);
mathMock.Verify(x => x.Multiply(It.IsAny<double>()), Times.Exactly(4));
}
答案 1 :(得分:-1)
在您的测试课程中,
using Math.Library;
using System;
using Moq;
using NUnit.Framework;
namespace UnitTests {
[TestFixture]
public class CMathTests {
CMath mathObj;
private IMath _math;
[SetUp]
public void Setup() {
mathObj = new CMath();// no need for this in mocking and its a wrong approach
_math = new Mock<IMath>();//initialize a mock object
}
[Test]
public void Add_Numbers9and5_Expected14() {
Assert.AreEqual(14, mathObj.Add(9, 5));
}
[Test]
public void Subtract_5From9_Expected4() {
Assert.AreEqual(4, mathObj.Subtract(9, 5));
}
[Test]
public void Multiply_5by9_Expected45() {
Assert.AreEqual(45, mathObj.Multiply(5, 9));
}
[Test]
public void When80isDividedby16_ResultIs5() {
Assert.AreEqual(5, mathObj.Divide(80, 16));
}
[Test]
public void When5isDividedBy0_ExceptionIsThrown() {
Assert.That(() => mathObj.Divide(1, 0),
Throws.Exception.TypeOf<DivideByZeroException>());
}
[Test]
public void Factorial_Of4_ShouldReturn24() {
Assert.That(mathObj.Factorial(4), Is.EqualTo(24));
}
[Test]
public void Factorial_Of4_CallsMultiply4Times() {
int count = 0;
_math.setup(x =>x.Multiply(It.IsAny<Int>(),It.IsAny<Int>())).Callback(() => count++);
_math.verify(x =>x.Multiply(),"Multiply is called"+ count+" number of times");
}
}
}
这将适合您的情况。类似地,您必须修改您的每个函数,就像在模拟中一样,如果它实现了接口,则无法实例化类的对象请参阅我已经为接口创建了模拟对象。
要了解有关Moq的更多信息,请访问here