gpt4 book ai didi

c# - 如何模拟在被测方法中实例化的对象

转载 作者:行者123 更新时间:2023-11-30 20:26:06 25 4
gpt4 key购买 nike

我有一些遗留代码并针对我对该代码所做的增强编写测试。我有一个类 SiteSession 并提取了一个接口(interface) ISiteSession,因此可以将依赖项注入(inject)调用类。

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

//...
}

调用类有一个构造函数,其中依赖项被注入(inject)到正在测试的 Controller 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);

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

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

private Mock<ISiteSession> _siteSession;

在测试设置方法中:_siteSession = new Mock<ISiteSession>();

并在测试方法中:_siteSession.Setup(x => x.Token).Returns("TestToken");

我试过类似的方法:

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

由于转换类型不同,这显然是不正确的,我想不出如何模拟 SiteSession 类,以便不调用实际的构造函数。我正在使用 NInject、NUnit 和 Moq

最佳答案

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

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

也就是说,根据当前的设计,如果您可以控制 Controller ,您可能需要 session 提供程序

public interface ISiteSessionProvider {
ISiteSession CreateSiteSession(CustomerDetails customerDetails);
}

Controller 将明确依赖于哪些

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

关于c# - 如何模拟在被测方法中实例化的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50465386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com