继承自抽象类的类如何进行单元测试

7

我的问题是,我想在我的抽象类中存根(stub)一个属性,因为我的测试类使用了该属性。我目前正在使用最新版本的Moq。

我的抽象类看起来像这样:

public abstract class BaseService
{
    protected IDrawingSystemUow Uow { get; set; }
}

我的测试类看起来像这样:

public class UserService : BaseService, IUserService
{
    public bool UserExists(Model model)
    {
        var user = this.Uow.Users.Find(model.Id);
        if(user == null) { return false; }

        reurn true;
    }
}

我无法弄清楚如何存根Uow属性。有人有什么线索吗?还是我的设计太糟糕了,需要将Uow属性移动到我的测试类中?

2个回答

11

你目前的设置不起作用,有一个简单的原因 - Uow 属性是不可覆盖的,而 Moq 的工作也到此为止了。无法覆盖,无法模拟

最简单的解决方法就是将该属性设置为可覆盖。将基类定义更改为:

public abstract class BaseService
{
    protected virtual IDrawingSystemUow Uow { get; set; }
}

现在可以使用Moq的protected功能(这要求您在测试类中包含 using Moq.Protected 命名空间):

// at the top of the file
using Moq.Protected;

// ...

var drawingSystemStub = new Mock<IDrawingSystemUow>();
var testedClass = new Mock<UserService>();
testedClass 
  .Protected()
  .Setup<IDrawingSystemUow>("Uow")
  .Returns(drawingSystemStub.Object);

// setup drawingSystemStub as any other stub

// exercise test
var result = testedClass.Object.UserExists(...);

非常感谢,这真的很有帮助!你的代码片段中只是一个小错误。Returns(drawingSystemStub) 应该替换为 Returns(drawingSystemStub.Object)。=) - Rikard
FYI @jimmy_keen - “Cannot override, cannot mock” 的链接已经失效。 - lukejkw

0

我认为在你的情况下,这是非常直接的。你只需要模拟IDrawingSystemUow服务而不是Uow属性。因此,你可以创建一个IDrawingSystemUow的模拟对象,通过Uow属性将其分配给UserService实例,然后运行测试(例如UserExists方法)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接