【发布时间】:2018-06-08 18:13:32
【问题描述】:
我这样做是否正确?如果是这样,我理解正确吗?我有点困惑。
我的项目设置在三个不同的层。 UI 层、业务层和数据访问层。业务层和数据访问层都是由接口构建的。
我正在尝试使用 NUnit 和 Moq 编写单元测试。
这是我的例子。我想测试 GetSum(int x, int y),这是一个只返回 x + y 的简单函数。此函数存在于 CalculatorLogic 中并实现 ICalculatorLogic。
public class CalculatorLogic : ICalculatorLogic
{
public int GetSum(int x, int y)
{
return x + y;
}
}
现在,这是我尝试编写 UnitTest 的方式。
[TestFixture]
public class CalculatorLogicTests
{
Mock<ICalculatorLogic> calculatorLogicMock;
ICalculatorLogic calculatorLogic;
public CalculatorLogicTests()
{
calculatorLogicMock = new Mock<ICalculatorLogic>();
// now i need to do this setup, right?
calculatorLogicMock.Setup(x => x.GetSum(It.IsAny<int>(), It.IsAny<int>())).Returns(6);
calculatorLogic = calculatorLogicMock.Object;
}
[Test]
public void GetSum_Test()
{
int expectedResult = 3 + 3;
var sum = calculatorLogic.GetSum(3, 3);
Assert.AreEqual(sum, expectedResult);
}
}
现在,以上通过了。它运行,它得到了我的期望。不过,感觉不对。它只是返回我在 Setup() 调用中设置的返回值。如果我在 Returns() 中放入 3 而不是 6,它将失败。
我一定是理解错了。否则,如果我告诉它要返回什么,我是否真的在测试我的函数?
【问题讨论】:
-
你模拟的任何东西都没有经过测试,所以这是一个毫无意义的测试,正如你所推测的那样。希望您的业务逻辑类将数据访问依赖项注入其中,这些是您想要模拟的东西,因此您仍然可以实际练习您的业务逻辑。
-
I have a blog post 你可能会觉得有帮助。
-
那么我不应该从接口实现我的业务逻辑吗?我还在我的控制器中使用依赖注入,并以这种方式将业务逻辑加载到它们中。我现在要读你的文章。谢谢。
-
连接您的 BL 取决于您。我倾向于不这样做,但如果我确实需要模拟某些东西,请使用虚拟方法。在少数情况下我不想总是运行业务逻辑。
-
你应该使用模拟来消除依赖而不是逻辑