c# - XUnit 如何对业务对象进行单元测试,我应该模拟所有内容吗?

标签 c# mocking xunit xunit.net

我正在尝试对我的业务对象进行单元测试 (XUnit),它需要 2 个参数并在返回输出之前执行一些操作。

    public OutPutModel MyBusinessObject(InputModel1 obj1, InputModel2 obj2)
    {
        // Performing some actions here including seding a call
        // to the data access layer to perform some db operation.
        return outPutModel;
    }

在我的 XUnit 中,我正在执行以下操作

    [Fact]
    public void MyBusinessObject_ReturnsOutPutModel()
    {
        var businessObjectMock = new Mock<IBusinessObject>();
        var obj1 = new Mock<InputModel1>();
        var obj2 = new Mock<InputModel2>();

        var outPutModel = new OutPutModel();

        var result = businessObjectMock.Setup(x => x.MyBusinessObject(obj1.Object, obj2.Object)).Returns(outPutModel);

        result.Equals(outPutModel);
    }

现在,我在我的业务对象中设置了一个断点 (public OutPutModel MyBusinessObject(InputModel1 obj1, InputModel2 obj2))。运行测试后,它没有达到断点,但仍然通过了测试。我在这里做错了吗?我应该模拟包括业务对象接口(interface)在内的所有内容,还是只模拟参数对象并调用业务对象的新实例? 附言忘了提,我知道在业务对象中包含数据库级别的东西不是一个好主意。不幸的是,考虑一下我别无选择。

最佳答案

您使用的模拟框架有误。您似乎也在尝试模拟被测系统。

经验法则,仅模拟绝对必要且仅当使用实现产生链式 react 时才模拟

例如,如果 BusinessObject 依赖于数据访问层,就像您在代码注释中指出的那样,

public class BusinessObject: IBusinessObject{

    private readonly IDataAccess dataAccess;

    public BusinessObject(IDataAccess dataAccess) {
        this.dataAccess = dataAccess;
    }

    public OutPutModel SomeBusinessMethod(InputModel1 obj1, InputModel2 obj2) {
        // Performing some actions here including seding a call
        // to the data access layer to perform some db operation.
        var outPutModel = dataAccess.SomeMethod(obj1, obj2);

        return outPutModel;
    }
}

您可以模拟被测方法中使用的依赖关系,然后调用被测类的实际实例。

例如

[Fact]
public void MyBusinessObject_ReturnsOutPutModel() {
    //Arrange
    var expected = new OutPutModel {
        // populate as needed
    }
    //mock the dependency
    var dataAccessMock = new Mock<IDataAccess>();
    //Setup the mocked dependency
    dataAccessMock
        .Setup(_ => _.SomeMethod(It.IsAny<InputModel1>(), It.IsAny<InputModel2>()))
        .Returns(expected);
    //inject the dependency into the subject under test
    var businessObject = new BusinessObject(dataAccessMock.Object);
    //needed objects for the test
    var obj1 = new InputModel1 {
        //populate as needed
    };
    var obj2 = new InputModel2 {
        //populate as needed
    };

    //Act
    var actual = businessObject.SomeBusinessMethod(obj1, obj2);

    //Assert
    Assert.AreEqual(expected, actual);
}

关于c# - XUnit 如何对业务对象进行单元测试,我应该模拟所有内容吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53266736/

相关文章:

c# - ELMAH 在哪里保存数据?

unit-testing - Groovy中的单元测试Abstract类

c# - 我在结合 dotMemory、xUnit 和 async 时做错了什么吗

c# - (什么时候)使用 FluentAssertions 是个好主意?

c# - 如何获取实现给定接口(interface)的所有加载类型的所有实例?

c# - 单例设计模式中的静态构造函数

c# - 具有一个公共(public)方法和多个私有(private)方法的单元测试类

c# - 如何访问C#项目目录

c# - 空间域图像卷积

Python 测试。 venv 库中的补丁方法