0

我目前正在 Moq'ing - 或尝试 Moq - 一个将数据插入数据库的类。

我正在模拟两个接口,并通过使用 DI 将它们设置为以下“外观”类的构造函数。

目前我所有的测试都运行并通过了,但我需要一些关于如何设置显示的“SaveServiceMessage”方法的返回布尔值的指导。

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

我需要知道的是,我如何能够 Moq 并获取“SaveServiceMessage”的布尔真或假值。我是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); 
    }
 }
4

2 回答 2

1

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

我们不会检查有关已保存消息的任何内容...

保存的消息是否应该使用 messageId?我们不检查它是不是 - 它不是,我们在创建消息时创建一个新的 id。如果保存的消息应该包含传入的 messageId,那么验证应该检查这一点。

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

消息类型是否正确?

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

我们将员工添加到本地员工列表中,然后不再对其进行任何操作。

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

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

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

我们将 ConversationStatus 传递给从未使用过的SaveServiceMessage()

于 2013-08-15T09:16:01.017 回答
0

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

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

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

于 2013-08-15T16:05:59.237 回答