从void方法中获取返回值方法

时间:2013-08-15 08:40:54

标签: c# .net unit-testing moq

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

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

目前我的所有测试都运行并通过,但我需要一些指导如何设置显示的'SaveServiceMessage'方法的返回bool值。

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

我需要知道的是,我如何使用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); 
    }
 }

2 个答案:

答案 0 :(得分:1)

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

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

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

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

邮件类型是否正确?

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

我们将员工添加到本地员工列表中,然后不再采取任何措施。

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

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

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

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

答案 1 :(得分:0)

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

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

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