使用nsubstitute截取一个类似于接口的方法

本文关键字:类似于 一个 接口 方法 nsubstitute 截取 使用 | 更新日期: 2023-09-27 18:30:05

这是我的第一篇文章!

我正试图使用nsubstitute编写一个单元测试,但我发现最后一点有点困难。

我在下面包含了一段代码,在调用模型上的方法时测试失败。有可能把这个方法截去吗?类似于接口

干杯,伙计们!期待您的回复

James

我的单元测试尝试

public class MyTests
{
    private IModelMapper _modelMapper;
    [SetUp]
    public void Setup()
    {
        _modelMapper = Substitute.For<IModelMapper>();
    }
    [Test]
    public void GetModel_Returns_A_Model()
    {
        var result = theClass.GetModel(new Booking {CurrencyCode = ""}, null);
        **UPDATE to include assert**
        // Assert
        Assert.IsInstance<BasketModel>(result);
    }
}

功能代码

public Model GetModel(Booking booking)
{
    var model = _modelMapper.Map(booking);
    // Is it possible to stub this out?  Similar to if it was an interface
    model.FormatPricing(somethingHere);
    return model;
}

UPDATE-说明返回类型

BasketModel model = _modelMapper.Map(booking);

更新#2-包括返回

var basketModel = new BasketModel();
BasketModel model = _modelMapper.Map(booking).Returns(basketModel);

使用nsubstitute截取一个类似于接口的方法

您能包括收到的测试失败消息吗?

以下是我倾向于对这类代码采取的一般方法。假设我们正在将IModelMapper注入测试中的类(近似代码;我还没有测试):

[SetUp]
public void Setup()
{
    _modelMapper = Substitute.For<IModelMapper>();
    theClass = new TheClass(_modelMapper);
}
[Test]
public void GetModel_Returns_Model_From_Mapper()
{
    // Arrange
    var booking = new Booking { CurrencyCode = "" };
    var expectedModel = new BasketModel();
    _modelMapper.GetModel(booking).Returns(expectedModel);
    // Act
    var result = theClass.GetModel(booking, null);
    // Assert
    Assert.AreSame(expectedModel, result);
}

如果你想去掉BasketModel.FormatModel(这是一个很大的"If"。如果可能的话,我建议使用真正的类型),那么你也需要替换BasketModel

请注意-NSubstitute将不适用于非虚拟方法,因此您可能需要BasketModel的接口,或者只确保在任何地方都使用虚拟方法。(再次,未经测试的代码先行)

[Test]
public void ModelReturnedShouldBeFormatted()
{
    // Arrange
    var booking = new Booking { CurrencyCode = "" };
    var expectedModel = Substitute.For<IBasketModel>();
    _modelMapper.GetModel(booking).Returns(expectedModel);
    // Act
    var result = theClass.GetModel(booking, null);
    // Assert
    expectedModel.Received().FormatModel(Arg.Any<SomethingHere>());
}

这是在测试对特定契约的遵守情况——TheClass将在映射器返回的BasketModel上调用FormatModel。如果您需要在测试中复制一些实现(同样,这通常是不鼓励的),您可以使用When..Do:

[Test]
public void FormatModel()
{
    // Arrange
    var booking = new Booking { CurrencyCode = "" };
    var expectedModel = Substitute.For<IBasketModel>();
    expectedModel
       .When(x => x.FormatModel(Arg.Any<SomethingHere>()))
       .Do(/* some action */);
    _modelMapper.GetModel(booking).Returns(expectedModel);
    // Act
    var result = theClass.GetModel(booking, null);
    // Assert
    // assertion here that depends on "some action" and result
}

希望这能有所帮助。