Moq';从void方法中调用返回值方法

本文关键字:方法 调用 返回值 void Moq | 更新日期: 2023-09-27 18:27:41

我目前正在创建或试图创建一个将数据插入数据库的类。

我正在嘲笑两个接口,并通过使用DI将它们设置为下面"Facade"类的构造函数。

目前,我所有的测试都在运行并通过,但我需要一些指导,告诉我如何设置所示"SaveServiceMessage"方法的返回布尔值。

目前我调用的"SynchEmployee"方法是无效的,在该方法内部调用"SaveServiceMessage"。在SaveServiceMessage中,我调用构造函数"SaveMessage"的模拟对象方法,这是访问真实非Moq'd对象中的数据库的方法。。

我需要知道的是,如何Moq并获得"SaveServiceMessage"的布尔值true或false。我是初来乍到的Moq'ing,所以希望你们能指导我。

这是我目前的测试:

[Test]
    public void TestSynchroniseEmployeeMethod()
    {
        var employee = new Employee();
        {
            employee.AOID = "A1";
            employee.ID = 1;
        }
        var guid = Guid.NewGuid();
        var serviceClientMock = new Mock<IService>();
        var serviceMessageReposMock = new Mock<IServiceMessageRepos>();
        var TestFacade = new Facade(serviceClientMock.Object, serviceMessageReposyMock.Object);
        TestFacade.SynchroniseEmployee(employee, guid);

        serviceMessageReposMock.Verify(x => x.SaveMessage(It.IsAny<ServiceMessage>()), Times.Exactly(1));
        serviceClientMock.Verify(x => x.SendServiceMessage(It.IsAny<ServiceMessage>(), It.IsAny<string>()), Times.Exactly(1));
    }
public class Facade
{
   IService _serviceMessage;
   IServiceRepos _serviceMessageRepos
    public Facade(IService serviceMessage, IServiceRepos serviceMessageRepos)
    { 
       _serviceMessage = serviceMessage;
       _serviceMessageRepos = serviceMessageRepos;
    }
    public bool SaveServiceMessage(ServiceMessage message, Guid correlationId, ConversationStatus status)
    {
        if (message != null)
        {
            message.CorrelationID = correlationId;
            _serviceMessageRepos.SaveMessage(message);
            return true;
        }
        return false;
    }
    public void SynchEmployee(Employee employee, Guid messageId)
    {
        var employees = new List<Employee>();
        employees.Add(employee);
        var message = new ServiceMessage(employee.ID, null, ServiceMessageType.EmployeeSyncRequest, Guid.NewGuid());
        message.ID = employee.ID.ToString();
        SaveServiceMessage(message, message.CorrelationID, ConversationStatus.NEW); 
        TransmitServiceMessage(message); 
    }
 }

Moq';从void方法中调用返回值方法

SynchEmployee()接收一个Employees和一个Guid(messageId),并在消息上调用IServiceRepos.SaveMessage()。似乎没有任何选择,所以单次测试应该足够了,但。。。

我们不检查有关已保存邮件的任何信息。。。

保存的邮件是否应该使用messageId?我们不检查它是不是,而是在创建消息时创建一个新的id。如果保存的消息应包含传入的messageId,则验证应对此进行检查。

员工Id是否从employee读取并放入消息中(它似乎被使用了两次,一次在ctor中,一次之后)

消息类型正确吗?

SendServiceMessage()的测试中存在一个从未调用过的验证。

我们将该员工添加到本地员工列表中,然后不做任何进一步的处理。

我们将消息id设置为员工id-这是正确的吗?如果是,那么我们为什么要传递messageId?

在ServiceMessage()的ctor中,我们传入一个新创建的GUID,然后将消息的ID设置为employeeId。ctor上的最后一个参数是ID。如果是,我们可以在此时传入值,而不是在之后设置它吗。

个人偏好:使用新的ServiceMessage(…)调用会对可测试性造成一些损害。如果我们传入一个服务来创建消息,那么我们可以验证该服务是否使用正确的参数进行了调用,并返回一个伪消息,我们可以在验证调用中使用该消息,而不必为该消息编写比较器。

我们将ConversationStatus传递到从未使用过的SaveServiceMessage()中。

我想你正在寻找这样的东西:

serviceMessageReposMock.SetUp(x => x.SaveServiceMessage(It.IsAny<ServiceMessage>(), GUId, status)).Returns(true);

这样SaveServiceMessage就不会被实际调用,但仍然可以验证输出。