NSubstitute创建两个替换实例

时间:2016-03-09 14:58:14

标签: c# tdd xunit nsubstitute

我有一个基础ApiController供我的控制器继承:

public BaseApiController(ILogger logger) : ApiController
{
    private readonly ILogger _logger;

    public BaseApiController(ILogger logger)
    {
        _logger = logger.ForContext("SomeContext");
    }
}

一个简单的控制器,它继承自基础控制器:

public SomeController : BaseApiController
{
    public SomeController(ILogger logger) : base(logger)
    { }

    public IHttpActionResult SomeAction()
    {
        _logger.Information("Start doing something...");

        //Do stuff...

        _logger.Information("End doing something...");

        return Ok();
    }
}

我使用Xunit和Nsu​​bstitute为控制器创建了一个简单的测试:

public void SomeAction_ReturnsOk()
{
    //Arrange
    var logger = Substitute.For<ILogger>();
    var controller = new SomeController(logger) {
        Request = Substitute.For<HttpRequestMessage>()
    };

    //Act
    var result = controller.SomeAction();

    //Assert
    logger.ReceivedWithAnyArgs().Information(Arg.Any<string>());
}

执行测试用例时,它无法声明它已收到对logger.Information()方法的零调用。在调试_receivedCalls属性(在替换的ILogger上)时,如果调试上下文在测试用例本身内,则显示对logger.ForContext()方法的单个调用(称为在基类构造函数上),但是当在controller.SomeAction()方法的上下文中查看调试时,相同的_receivedCalls属性显示对logger.Information()的两次调用。预期但不是ForContext()的号召。

所以在我看来,由于某些原因,Nsubstitute正在创建替代类的两个独立实例,一个在基本控制器的上下文中,另一个在实际控制器中 - 为什么这样,我该如何避免呢?

1 个答案:

答案 0 :(得分:2)

你需要像这样存档ForContext

public void SomeAction_ReturnsOk()
{
    //Arrange
    var logger = Substitute.For<ILogger>();
    logger.ForContext(Arg.Any<string>()).Returns(logger);
    var controller = new SomeController(logger) {
        Request = Substitute.For<HttpRequestMessage>()
    };

    //Act
    var result = controller.SomeAction();

    //Assert
    logger.Received().Information(Arg.Any<string>());
}

我将断言更改为:

logger.Received().Information(Arg.Any<string>());

OR:

logger.ReceivedWithAnyArgs().Information("");
相关问题