有人可以帮我解决这个错误消息吗?我不明白为什么演员阵容不起作用:
消息:System.InvalidCastException:无法转换类型的对象 输入“Castle.Proxies.ObjectProxy” 'Automation.Pages.ToolbarElements.ElementsWithActiveState.ActiveStateElements'。
这是我的测试:
[TestFixture]
[Category("unit")]
class ActiveStateElementBehaviorTests
{
[Test]
public void GetCurrentElementState_StateIsActive_ReturnActive()
{
var moqElement = new Mock<IActiveState>();
moqElement.Setup(x => x.IsElementInActiveState()).Returns(() => true);
var behavior = new ActiveStateElementBehavior(moqElement.Object);
behavior.GetCurrentElementState().Should().BeEquivalentTo(ElementState.Active);
}
}
这是我的代码:
public class ActiveStateElementBehavior : IElementStateBehavior
{
public ActiveStateElementBehavior(IActiveState toolbarElement)
{
Element = (ActiveStateElements)toolbarElement;
}
public ENAEPToolbarElement Element { get; }
public ElementState GetCurrentElementState()
{
var element = (ActiveStateElements) Element;
return element.IsElementInActiveState() ? ElementState.Active :
element.IsButtonInEnabledState() ? ElementState.Default :
ElementState.Disabled;
}
}
public interface IActiveState
{
bool IsElementInActiveState();
}
你的模拟是
IActiveState
,而不是ActiveStateElements
。
当您调用
new Mock<IActiveState>()
时,它会动态创建一些实现接口 IActiveState
的新类型。
这个新类型不能转换为 ActiveStateElements
,这意味着构造函数中的转换将会失败。
你可以像
var moqElement = new Mock<ActiveStateElements>()
一样创建模拟,但我想这行不通。 ActiveStateElements
上的方法可能不是 virtual
,因此您无法设置任何方法。
真正的问题是
ActiveStateElementBehavior
对消费者说“我需要一些实现IActiveState
的东西”。然后在内部它需要一个 ActiveStateElements
的实例。
您应该在
IActiveState
上定义所需的任何其他方法,并且 ActiveStateElementBehavior
不应该有任何对 ActiveStateElements
的强制转换或引用。它应该只知道接口 IActiveState
现有的答案很好,我将给出另一个答案,因为您经常会在 HealthChecks 中遇到它:
尝试测试一下:
public class StartupBackgroundService : BackgroundService
{
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var scope = _services.CreateScope())
{
// TAKE NOTE OF THE SERVICE YOU NEED TO MOCK
var healthCheck = scope.ServiceProvider.GetRequiredService<HealthCheckService>();
var report = healthCheck.CheckHealthAsync();
我必须像这样模拟 Scope 和 HealthCheckService:
// Arrange
var mockHealthCheck = new Mock<HealthCheckService>(); // <-- THIS HAS TO BE CORRECT OTHERWISE YOU GET THE ERROR IN QUESTION
var mockStartCheck = new Mock<StartupHealthCheck>();
var mockLogger = new Mock<ILogger<StartupHealthCheck>>();
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider.Setup(provider => provider.GetService(typeof(HealthCheckService))).Returns(mockHealthCheck.Object);
var serviceScope = new Mock<IServiceScope>();
serviceScope.Setup(x => x.ServiceProvider).Returns(serviceProvider.Object);
var serviceScopeFactory = new Mock<IServiceScopeFactory>();
serviceScopeFactory
.Setup(x => x.CreateScope())
.Returns(serviceScope.Object);
serviceProvider
.Setup(x => x.GetService(typeof(IServiceScopeFactory)))
.Returns(serviceScopeFactory.Object);
var service = new StartupBackgroundService(mockStartCheck.Object, serviceProvider.Object, mockLogger.Object);
// Act
// This magically calls ExecuteAsync
var res = service.StartAsync(It.IsAny<CancellationToken>());