XUnit, как провести модульное тестирование бизнес-объекта и надо ли мне все издеваться? - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь выполнить модульное тестирование (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)),После запуска теста он не достигает точки останова, но все же проходит тест.Я что-то здесь не так делаю?Должен ли я издеваться над всем, включая интерфейс бизнес-объекта, или просто издеваться над объектами параметров и вызывать новый экземпляр бизнес-объекта?PS Забыл упомянуть, я знаю тот факт, что не очень хорошая идея иметь вещи уровня db в бизнес-объектах.К сожалению, просто подумайте, у меня нет выбора.

1 Ответ

0 голосов
/ 12 ноября 2018

Вы неправильно используете структуру насмешки.Вы также, похоже, пытаетесь издеваться над тестируемой системой.

Правило большого пальца, только издевайтесь над тем, что абсолютно необходимо, и только в том случае, если использование реализации стучит в эффекты

Если, например, 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);
}
...