Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用NserviceBus。测试当代码未通过消息处理程序启动时,如何测试已发布事件_C#_.net_Unit Testing_Moq_Nservicebus - Fatal编程技术网

C# 使用NserviceBus。测试当代码未通过消息处理程序启动时,如何测试已发布事件

C# 使用NserviceBus。测试当代码未通过消息处理程序启动时,如何测试已发布事件,c#,.net,unit-testing,moq,nservicebus,C#,.net,Unit Testing,Moq,Nservicebus,问题 如果正在测试的当前方法是通过传入消息(进入处理程序)以外的其他方法启动的,那么如何测试事件的发布。NServiceBus.Testing(据我所知)的问题在于它非常适合于测试处理程序,而这些处理程序又会导致消息/事件被发送/发布 背景: 我们有许多遗留系统,在向适当的SOA实现过渡的过程中,我们需要与一些遗留数据库作业集成。这些作业每15分钟在数据库上执行一次操作,我们希望在某些情况发生时将这些操作挂接到并发布事件 我们有一个在NsbHost中运行的windows服务,但不包含任何处理程序

问题

如果正在测试的当前方法是通过传入消息(进入处理程序)以外的其他方法启动的,那么如何测试事件的发布。NServiceBus.Testing(据我所知)的问题在于它非常适合于测试处理程序,而这些处理程序又会导致消息/事件被发送/发布

背景

我们有许多遗留系统,在向适当的SOA实现过渡的过程中,我们需要与一些遗留数据库作业集成。这些作业每15分钟在数据库上执行一次操作,我们希望在某些情况发生时将这些操作挂接到并发布事件

我们有一个在NsbHost中运行的windows服务,但不包含任何处理程序。相反,我们使用Quartz创建一个内部cron作业,该作业每分钟运行一次,轮询DB以查找与指定模式匹配的记录,并在更新DB之前发布一个事件,以表明我们已经处理了该记录。这就是我们整合新旧系统的方式

显然,这不是一个理想的情况,但考虑到我们正处于SOA实现的过渡阶段,它和我们现在的情况一样好

详细信息和代码

我们正在发布的事件界面如下所示

    public interface IPremiumAdjustmentFinalised
    {
        string PolicyNumber { get; set; }
        decimal Amount { get; set; }
        DateTime FinalisedOn { get; set; }
    }
var myBus = new myBus();
eventPublisher = new AdjustmentFinaliserEventPublisher(myBus);
eventPublisher.UpdateAndPublishFinalisedAdjustments();
实际发布事件的代码是

    Bus.Publish<IPremiumAdjustmentFinalised>(e =>
    {
        e.Amount = AdjustmentAmount;
        e.PolicyNumber = PolicyNumber;
        e.FinalisedOn = LastModifiedOn;
    });
Bus.Publish(e=>
{
e、 金额=调整金额;
e、 保单编号=保单编号;
e、 finalizedon=LastModifiedOn;
});
这一切都很好,我们可以使用MOQ测试调用,因此:

    eventPublisher.MethodToTest();
    bus.Verify(x => x.Publish(It.IsAny<Action<IPremiumAdjustmentFinalised>>()), Times.Once);
eventPublisher.MethodToTest();
bus.Verify(x=>x.Publish(It.IsAny()),Times.one);
其中,总线是插入到构造函数中的新模拟

但我想测试ipremiumadjustmentfinalized中的值。我发现这非常困难,我想主要是因为它是一个接口,而不是一个具体的类

我们已经尝试使用NServiceBus.Testing来尝试和检查生成的事件,但没有效果


有人知道如何在给定场景中测试事件中的值吗?

我们提出了两种解决方案

解决方案1:

创建一个继承接口的具体类,并发布该类

public class PremiumAdjustmentFinalisedEvent : IPremiumAdjustmentFinalised
{
    public string PolicyNumber { get; set; }
    public decimal Amount { get; set; }
    public DateTime FinalisedOn { get; set; }
}
此类仅在发送方中使用,另一端的处理程序仍将侦听类型为IPREMIUMADJUSTMENTFinalized的事件

发送事件将更改为

var message = new PremiumAdjustmentFinalisedEvent
{
    Amount = AdjustmentAmount,
    PolicyNumber = PolicyNumber,
    FinalisedOn = LastModifiedOn
};    
Bus.Publish<IPremiumAdjustmentFinalised>(message);

我喜欢这个解决方案,因为它不会仅仅为了测试而更改实时代码,但缺点是IBus的大量实现中包含大量未实现的方法。

在找到这篇文章后,在谷歌搜索结果周围搜索了几天之后,除了这篇文章之外,似乎没有其他真正的指导。在实现了解决方案2之后,我决定找到一种更轻松的方法,并提出了以下使用Moq作为模拟库的方法

///Declarations
private Mock<IPremiumAdjustmentFinalised > _mockEvent = new Mock<IPremiumAdjustmentFinalised >();
private readonly Mock<IBus> _mockBus = new Mock<IBus>();
private SomeEventPublisher _someEventPublisher;

[SetUp]
public void Setup()
{
     //Instruct moq to set up implementations for the event interface's properties.
    _mockEvent.SetupAllProperties();

    _mockBus.Setup(b => b.Publish(It.IsAny<Action<IPremiumAdjustmentFinalised>>()))
    .Callback((Action<IPremiumAdjustmentFinalised> messageConstructor) =>
    {
        //Execute the constructor provided in the action in the event publisher, so the event data can be interrogated.
        messageConstructor(_mockEvent.Object);
    });

    _someEventPublisher = new SomeEventPublisher(_mockBus);
}


[Test]
public void SomeEventPublisherTest()
{
    _someEventPublisher.PublishSomeEvent(AdjustmentAmount, LastModifiedOn, PolicyNumber)

    Assert.AreEqual(_mockEvent.Object.Amount, AdjustmentAmount);
    Assert.AreEqual(_mockEvent.Object.FinalisedOn, LastModifiedOn);
    Assert.AreEqual(_mockEvent.Object.PolicyNumber, PolicyNumber);
}
///声明
私有模拟_mockEvent=new Mock();
私有只读Mock_mockBus=new Mock();
私有SomeEventPublisher\u SomeEventPublisher;
[设置]
公共作废设置()
{
//指示moq为事件接口的属性设置实现。
_mockEvent.SetupAllProperties();
_mockBus.Setup(b=>b.Publish(It.IsAny()))
.Callback((操作消息构造函数)=>
{
//执行事件发布程序中操作中提供的构造函数,以便查询事件数据。
messageConstructor(_mockEvent.Object);
});
_someEventPublisher=新的someEventPublisher(_mockBus);
}
[测试]
public void SomeEventPublisherTest()
{
_someEventPublisher.PublishSomeEvent(AdjustmentAmount、LastModifiedOn、PolicyNumber)
Assert.AreEqual(_mockEvent.Object.Amount,AdjustmentAmount);
Assert.AreEqual(_mockEvent.Object.finalizedon,LastModifiedOn);
Assert.AreEqual(_mockEvent.Object.PolicyNumber,PolicyNumber);
}
var myBus = new myBus();
eventPublisher = new AdjustmentFinaliserEventPublisher(myBus);
eventPublisher.UpdateAndPublishFinalisedAdjustments();
///Declarations
private Mock<IPremiumAdjustmentFinalised > _mockEvent = new Mock<IPremiumAdjustmentFinalised >();
private readonly Mock<IBus> _mockBus = new Mock<IBus>();
private SomeEventPublisher _someEventPublisher;

[SetUp]
public void Setup()
{
     //Instruct moq to set up implementations for the event interface's properties.
    _mockEvent.SetupAllProperties();

    _mockBus.Setup(b => b.Publish(It.IsAny<Action<IPremiumAdjustmentFinalised>>()))
    .Callback((Action<IPremiumAdjustmentFinalised> messageConstructor) =>
    {
        //Execute the constructor provided in the action in the event publisher, so the event data can be interrogated.
        messageConstructor(_mockEvent.Object);
    });

    _someEventPublisher = new SomeEventPublisher(_mockBus);
}


[Test]
public void SomeEventPublisherTest()
{
    _someEventPublisher.PublishSomeEvent(AdjustmentAmount, LastModifiedOn, PolicyNumber)

    Assert.AreEqual(_mockEvent.Object.Amount, AdjustmentAmount);
    Assert.AreEqual(_mockEvent.Object.FinalisedOn, LastModifiedOn);
    Assert.AreEqual(_mockEvent.Object.PolicyNumber, PolicyNumber);
}