在下面的代码中,我想模拟GetTitle(int id)
类中FooBase
的数据库操作。但我想在重写GetTitle(int id)
中测试验证部分。
我想测试重写方法但是模拟基本方法
我如何模拟虚拟方法并测试它的重写?
public abstract class FooBase
{
public virtual string GetTitle(int id) { return "Title From DB" /*Select From DB*/; }
}
public class Foo : FooBase
{
public override string GetTitle(int id)
{
if (id < 0)
return "Invalid id";
/*Doing somethings like other validations and etc*/
return $"Valid ID ({base.GetTitle(id)})";
}
}
public class FooTests
{
[Fact]
public void GetTitle() // Fails
{
// Arrange
var expectedID = 1;
var expectedResult = "Test";
var fooMock = new Mock<Foo>();
fooMock.Setup(x => x.GetTitle(It.IsAny<int>())).Returns(expectedResult);
var foo = fooMock.Object;
// Act
var title = foo.GetTitle(expectedID);
// Assert
fooMock.Verify(x => x.GetTitle(It.Is<int>(c => expectedID == c)), Times.Once);
Assert.Equal($"Valid ID ({expectedResult})", title);
}
}
答案 0 :(得分:1)
如果你可以将你的逻辑分成不同的方法(也可能是更好的设计),那么你可以使用Moq的CallBase
属性来使测试调用模拟方法。
public abstract class FooBase
{
public virtual string GetTitle(int id) { return "Title From DB" /*Select From DB*/; }
}
public class Foo : FooBase
{
public virtual string GetValidatedTitle(int id)
{
if (id < 0)
return "Invalid id";
/*Doing somethings like other validations and etc*/
return $"Valid ID ({GetTitle(id)})";
}
}
public class FooTests
{
[Fact]
public void GetTitle() // Now Passes
{
// Arrange
var expectedID = 1;
var expectedResult = "Test";
var fooMock = new Mock<Foo>() { CallBase = true };
fooMock.Setup(x => x.GetTitle(It.IsAny<int>())).Returns(expectedResult);
var foo = fooMock.Object;
// Act
var title = foo.GetValidatedTitle(expectedID);
// Assert
fooMock.Verify(x => x.GetTitle(It.Is<int>(c => expectedID == c)), Times.Once);
Assert.Equal($"Valid ID ({expectedResult})", title);
}
}