MJR*_*MJR 5 c# unit-testing moq
好的,我正在做一些单元测试,我的理解是(基于 Roy Osherove 的“单元测试的艺术”),如果您正在访问数据库或实际保存文件,那么您是集成测试,而不是单元测试。
鉴于此,我有以下几点(是的,我知道这违反了 SRP,但它说明了我的观点):
public class PrimeChecker : IPrimeChecker
{
public bool IsPrime(int num)
{
if (num < 2)
{
return false;
}
if (num > 2 && num % 2 == 0)
{
return false;
}
if (num % 2 != 0)
{
for (int i = 3; (i * i) <= num; i += 2)
{
if (num % i == 0)
{
return false;
}
}
}
return true;
}
public bool Save()
{
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
注意 Save() 方法现在只是一个存根。
我正在尝试使用 Moq 来模拟保存。所以我的测试看起来像这样:
[Test]
public void Save_WhenCalled_ExecutesSave()
{
var mock = new Mock<IPrimeChecker>();
mock.Setup(x => x.Save());
IPrimeChecker checker = mock.Object;
checker.Save();
mock.Verify(x => x.Save(), Times.Once);
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我的类中有一个功能齐全的 Save() 方法,这是模拟功能的正确方法吗?因为正如我之前所说的,我的理解是对于单元测试,我不应该实际写入文件/保存到数据库。
如果这是不正确的,什么应该我做?
假设您的检查器依赖于需要保存的内容。
可以说
public interface IPrimeDb {
bool Save(int prime);
}
Run Code Online (Sandbox Code Playgroud)
检查器看起来像这样
public class PrimeChecker {
private IPrimeDb primeDb;
public PrimeChecker(IPrimeDb db) {
this.primeDb = db;
}
public bool IsPrime(int num) {
if (num < 2) {
return false;
}
if (num > 2 && num % 2 == 0) {
return false;
}
if (num % 2 != 0) {
for (int i = 3; (i * i) <= num; i += 2) {
if (num % i == 0) {
return false;
}
}
}
return true;
}
public bool Save(int prime) {
if (IsPrime(prime))
return primeDb.Save(prime);
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
在提供有效素数时测试是否正在调用保存的测试可能如下所示。
[TestMethod]
public void Save_WhenCalled_ExecutesSave() {
//Arrange
var num = 3;
var mock = new Mock<IPrimeDb>();
var sut = new PrimeChecker(mock.Object);
mock.Setup(_ => _.Save(num)).Returns(sut.IsPrime(num));
//Act
var actual = sut.Save(num);
//Assert
Assert.IsTrue(actual);
mock.Verify(_ => _.Save(num), Times.AtMostOnce());
}
Run Code Online (Sandbox Code Playgroud)
在单元测试时,您倾向于模拟被测对象的依赖项,以避免出现不良行为。这允许单独进行测试。
| 归档时间: |
|
| 查看次数: |
2084 次 |
| 最近记录: |