当前位置: 首页 > 知识库问答 >
问题:

如何模拟被测试方法中实例化的对象

邓禄
2023-03-14

我有一些遗留代码,并对我在该代码上所做的增强进行了编写测试。我有一个类SiteSession,并提取了一个接口ISiteSession,以便将依赖项注入到调用类中。

public class SiteSession : ISiteSession
{
    public SiteSession(string userName, string externalRef, IePermitProAdapterClient ePermitService)
    {
        //.......
    }

    //...
}

调用类有一个构造函数,在该构造函数中,依赖项被注入到正在测试的控制器CustomerDetails中

private readonly ICustomerDetails _customerDetails;
private ISiteSession _siteSession;

public SsoController(ICustomerDetails customerDetails, ISiteSession siteSession)
{
    _customerDetails = customerDetails;

    _siteSession = siteSession;
}

public ActionResult CustomerDetails(CustomerDetails customerDetails)
{
    //.....  
    //...
    //...    

    _siteSession = new SiteSession(customer.Username, customer.CustomerRef, ePermitService);

    //.....
    //...
    //...
}

现在,我的测试方法已经嘲弄了依赖关系,并且我对为这个控制器或代码的任何其他部分创建的任何测试都没有问题。但是,当调用该控制器上的测试CustomerDetails时,实际的构造函数调用是对SiteSession类进行的,而我无法注入模拟并中断实际调用。我的测试代码如下:

private Mock<ISiteSession> _siteSession;
 _siteSession = new Mock<SiteSession>(_customer.Object.Username, _customer.Object.CustomerRef, null);

这显然是不正确的,因为转换中有不同的类型,而且我无法想出如何模拟SiteSession类,这样就不会调用实际的构造函数。我正在使用NInject、NUnit和Moq

共有1个答案

顾兴昌
2023-03-14

这是一个设计问题。通过在控制器中手动创建实例,控制器与实现紧密耦合,这使得模拟非常困难。回顾您的设计选择,因为当前的示例在最终目标方面不是很清楚。

提供适当的单元测试的困难应该是设计问题的直接指标。

也就是说,基于当前的设计,并且如果您控制了控制器,您可能需要会话提供程序

public interface ISiteSessionProvider {
    ISiteSession CreateSiteSession(CustomerDetails customerDetails);
}
public class SsoController: Controller {
    private readonly ICustomerDetails _customerDetails;
    private readonly ISiteSessionProvider siteSessionProvider;

    public SsoController(ICustomerDetails customerDetails, ISiteSessionProvider siteSessionProvider) {
        _customerDetails = customerDetails;
        this.siteSessionProvider = siteSessionProvider;
    }

    public ActionResult CustomerDetails(CustomerDetails customerDetails) {
        //...

        ISiteSession siteSession = siteSessionProvider.CreateSiteSession(customerDetails);

        //...
    }
}
//Arrange
var sessionMock = new Mock<ISiteSession>();
sessionMock.Setup(_ => _.Token).Returns("TestToken");

var providerMock = new Mock<ISiteSessionProvider>();
providerMock
    .Setup(_ => _.CreateSiteSession(It.IsAny<CustomerDetails>()))
    .Returns(sessionMock.Object);

var controller = new SsoController(Mock.Of<ICustomerDetails>(), providerMock.Object);

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

//Assert
//...
public ISiteSession CreateSiteSession(CustomerDetails customerDetails) {
    //...

    return new SiteSession(customer.Username, customer.CustomerRef, ePermitService);
}
 类似资料:
  • 澄清一下:我选择使用主题的一个实际的嵌入式实例,以便用一个实际的实例进行测试,而不是在mockito中嘲弄hand off。这样我就可以测试我的自定义编码器和解码器是否能够正常工作,并且当我使用一个真实的kafka实例时不会失败。

  • 问题内容: 我有一个要测试的类。只要有可能,我都会对该类进行依赖注入,该注入依赖于其他类的对象。但是,我遇到了一种情况,我想在不重新构造代码的情况下模拟对象,而不是应用DI。 这是要测试的课程: 我为此的测试课程是: 我想不出一种解决方案来模拟Dealer类中的打印对象。自从我在Test类中对其进行了模拟,但是它是在被测试的方法中创建的。我做了研究,但找不到任何好处。资源。 我知道从该方法中创建P

  • 问题内容: 这是该结构及其方法的示例代码 然后我想从驻留在包外部的函数中调用方法,示例代码 我想通过模拟A 的方法来编写该功能的测试用例。 在Java中,我们有mockito,jmock框架来存根方法调用。 有什么办法,我们可以在不引入源代码的情况下模拟struct的方法调用吗? 问题答案: 要模拟方法调用,您需要模拟您的结构。 对于您提供的代码示例,我建议创建一个实现您的调用的接口。您的实际结构

  • 如何模拟返回已强制转换的模拟对象的方法。 试验方法。

  • 我有一个测试,如下所示,在给定条件下,我想确保。 然而,它错误地指出 错误出现在行 应为不是模拟对象。如何测试为非模拟对象调用的方法? 我在如何验证一个非模拟对象的方法中看到了答案?,但这仍然是使用模拟和间谍。我希望找到一种不需要嘲笑我已经拥有的类实例的方法。 (注:以上内容以科特林书写)

  • 问题内容: 似乎模拟仅验证模拟对象的方法是否被调用,并且模拟对象始终具有类似以下内容的东西 但是我可以创建一个模拟对象并定义 然后验证另一个对象的方法是否被调用吗? 这是我想做的事情:我定义了一个模拟环境,无论发生什么情况都返回一个响应。但是然后我想验证在不同情况下调用anotherObj的不同方法。 怎么做? 问题答案: 您可以为此使用Mockito Spy。如果您设置为间谍,则可以验证该对象上