使用nsubstitute来删除类似接口的方法

时间:2014-11-10 23:27:14

标签: c# unit-testing nsubstitute

这是我的第一篇文章!

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

我在下面包含了一段代码,在模型上调用方法时测试失败。是否可以将此方法存根?类似于它是一个接口

干杯!期待您的回复

詹姆斯

我的单元测试尝试

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;
}

更新 - 说明返回类型

BasketModel model = _modelMapper.Map(booking);

更新#2 - 包含退货

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

1 个答案:

答案 0 :(得分:0)

您可以列出您正在获得的测试失败消息吗?

这是我倾向于采用这种代码的一般方法。假设我们正在将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(这是一个很大的&#34;如果&#34;。如果可能的话,我会建议使用真实的类型),那么你想要替代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会在映射器返回的FormatModel上调用BasketModel。如果您需要在测试中复制某些实现(同样,通常不鼓励这样做),您可以使用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
}

希望这有帮助。