Sta*_*tan 7 c# tdd unit-testing moq mocking
我已经使用TDD一段时间但现在我正在看嘲笑框架,我没有得到一些东西.这个问题对于经验丰富的人来说可能听起来很愚蠢,但我只是不明白.我使用的库是Moq + xUnit.
Calculator如果我明确地说2 + 2将4在此行上返回mock.Setup(x => x.Add(2, 2)).Returns(4);然后断言它,那么测试类有什么意义呢?
当然结果将是4,我只是"强迫"它在测试本身上方的几行中返回4.现在即使在我的实施中,如果我做return a * b;而不是return a + b;测试将通过.
这是同一计算器测试的另一个例子.http://nsubstitute.github.io/
namespace UnitTestProject1
{
using Xunit;
using Moq;
public class CalculatorTests
{
private readonly ICalculator _calculator;
public CalculatorTests()
{
var mock = new Mock<ICalculator>();
mock.Setup(x => x.Add(2, 2)).Returns(4);
mock.Setup(x => x.Subtract(5, 2)).Returns(3);
this._calculator = mock.Object;
}
[Fact]
public void Calculator_Should_Add()
{
var result = _calculator.Add(2, 2);
Assert.Equal(4, result);
}
[Fact]
public void Calculator_Should_Subtract()
{
var result = _calculator.Subtract(5, 2);
Assert.Equal(3, result);
}
}
public class Calculator : ICalculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Subtract(int a, int b)
{
return a - b;
}
}
public interface ICalculator
{
int Add(int a, int b);
int Subtract(int a, int b);
}
}
Run Code Online (Sandbox Code Playgroud)
目的是能够根据计算器测试类,而不需要计算器是自己的.在您的测试中,您知道计算器不能成为失败的原因,因为正在返回正确的答案.
通过隔离测试中的代码,您将能够测试真实的代码单元.并且还要确切了解导致测试失败的原因.
你不应该对模拟进行单元测试.假设您要测试使用IService和IStorage的对象OrderProcessor.
对于"单元测试"OrderProcessor,您可以模拟IService和IStorage的行为,以便您可以在不使用Web服务和数据库的情况下验证目标类是否按预期工作.
即
class OrderProcessor{
private IService service, IStorage storage;
public OrderProcessor(IService service, IStorage storage){ // bla bla}
public ProcessOrder(Order o){
// do something
// use the service
var price = service.GetPrice(..);
// store the result
storage.StoreOrder(order);
}
}
// test. Define mocks
var mockStorage = new Mock<IStorage>();
var mockService = new Mock<IService>();
// Setup test behaviour
mockStorage.Setup(m => m.GetPrice("X10").Returns(11);
mockStorage.Setup(m => m.GetPrice("X11").Returns(99);
...
var target = new OrderProcessor(mockService.Object, mockStorage.Object);
// ...
target.ProcessOrder(o);
// Verify the storing was called
mockStorage.Verify(m => m.StoreOrder(o), Times.Once());
// Verify the service was called X times
mockService .Verify(m => m.GetPrice(x), Times.Exactly(order.Items.Count));
Run Code Online (Sandbox Code Playgroud)
在这种情况下,嘲笑没有意义 - 这个例子太简单了.你没有通过嘲弄获得任何东西ICalculator.
当你有一个复杂的实现时,你会模拟,并且你正在尝试测试依赖于该接口实现的东西.在这种情况下你没有这样做,你正在测试一个模拟实现.测试模拟实现毫无意义.
例如,假设您的计算器实现实际上调用了Web服务来执行计算,并且您尝试测试消耗服务计算的内容.你的目标不是测试计算器 - 你的目标是测试使用计算器的东西.让测试依赖于正在运行的Web服务是愚蠢的,并且可能导致您的测试意外失败.
| 归档时间: |
|
| 查看次数: |
634 次 |
| 最近记录: |