验证与起订量的参考参数的值 [英] Verify value of reference parameter with Moq

查看:113
本文介绍了验证与起订量的参考参数的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚切换到起订量,并遇到了一个问题。我测试,创建一个业务对象的新实例,设置用户输入值对象的属性和调用方法(SaveCustomerContact)保存新对象的方法。因为它通过一个远程层业务对象作为ref参数传递。我需要测试传递给SaveCustomerContact对象有其所有属性设置的预期,而是因为它被实例化在控制器的新方法,我似乎无法这样做。

I just switched to Moq and have run into a problem. I'm testing a method that creates a new instance of a business object, sets the properties of the object from user input values and calls a method (SaveCustomerContact ) to save the new object. The business object is passed as a ref argument because it goes through a remoting layer. I need to test that the object being passed to SaveCustomerContact has all of its properties set as expected, but because it is instantiated as new in the controller method I can't seem to do so.

public void AddContact() {

    var contact = new CustomerContact() { CustomerId = m_model.CustomerId };

    contact.Name = m_model.CustomerContactName;
    contact.PhoneNumber = m_model.PhoneNumber;
    contact.FaxNumber = m_model.FaxNumber;
    contact.Email = m_model.Email;
    contact.ReceiveInvoiceFlag = m_model.ReceiveInvoiceFlag;
    contact.ReceiveStatementFlag = m_model.ReceiveStatementFlag;
    contact.ReceiveContractFlag = m_model.ReceiveContractFlag;
    contact.EmailFlag = m_model.EmailFlag;
    contact.FaxFlag = m_model.FaxFlag;
    contact.PostalMailFlag = m_model.PostalMailFlag;
    contact.CustomerLocationId = m_model.CustomerLocationId;

    RemotingHandler.SaveCustomerContact( ref contact );
}

下面的测试:

[TestMethod()]
public void AddContactTest() {

    int customerId = 0;

    string name = "a";

    var actual = new CustomerContact();

    var expected = new CustomerContact() {
        CustomerId = customerId,
        Name = name
    };

    model.Setup( m => m.CustomerId ).Returns( customerId );
    model.SetupProperty( m => model.CustomerContactName, name );
    model.SetupProperty( m => m.PhoneNumber, string.Empty );
    model.SetupProperty( m => m.FaxNumber, string.Empty );
    model.SetupProperty( m => m.Email, string.Empty );
    model.SetupProperty( m => m.ReceiveInvoiceFlag, false );
    model.SetupProperty( m => m.ReceiveStatementFlag, false );
    model.SetupProperty( m => m.ReceiveContractFlag, false );
    model.SetupProperty( m => m.EmailFlag, false );
    model.SetupProperty( m => m.FaxFlag, false );
    model.SetupProperty( m => m.PostalMailFlag, false );
    model.SetupProperty( m => m.CustomerLocationId, 0 );

    remote
        .Setup( r => r.SaveCustomerContact( ref actual ) )
        .Callback( () => Assert.AreEqual( actual, expected ) );

    target.AddContact();

}

这仅仅是最近许多尝试得到阿霍德的该参数。作为参考,实际值不从其初始(构成)的状态的变化。

This is just the most recent of many attempts to get ahold of that parameter. For reference, the value of actual does not change from its initial (constructed) state.

移动Assert.AreEqual(预期,实际)目标呼叫失败之后。如果我添加.Verifiable()来设置,而不是.CallBack,然后调用remote.Verify目标后(或者,我认为,设置模拟严格),它总是失败,因为我在测试中提供参数不是同一个实例是在控制器的方法创建的。

Moving the Assert.AreEqual(expected, actual) after the target call fails. If I add .Verifiable() to the setup instead of the .CallBack and then call remote.Verify after the target (or, I assume, set the mock to strict) it always fails because the parameter I provide in the test is not the same instance as the one that is created in the controller method.

我使用起订量3.0.308.2。如何测试这个任何想法,将不胜感激。谢谢!

I'm using Moq 3.0.308.2. Any ideas on how to test this would be appreciated. Thanks!

推荐答案

我不能为您提供一个确切的解决方案,但更好的方法是隐藏传递由-REF一个适配器,它由值取参数,并将其转发到RemotingHandler后面语义。这将是更容易戏弄,会删除该界面中的裁判疣(我一直怀疑ref参数:-))

I can't offer you an exact solution, but an alternative would be to hide the pass-by-ref semantics behind an adapter, which takes the parameter by value and forwards it to the RemotingHandler. This would be easier to mock, and would remove the "ref" wart from the interface (I am always suspicious of ref parameters :-) )

编辑:

或者你可以使用,而不是一个模拟存根,例如:

Or you could use a stub instead of a mock, for example:

public class StubRemotingHandler : IRemotingHandler
{
    public CustomerContact savedContact;

    public void SaveCustomerContact(ref CustomerContact contact)
    {
        savedContact = contact;
    }
}

您现在可以检查在测试中保存的对象:

You can now examine the saved object in your test:

IRemotingHandler remote = new StubRemotingHandler();
...
//pass the stub to your object-under-test
...
target.AddContact();
Assert.AreEqual(expected, remote.savedContact);

您也说您的评论:

我讨厌开始包装后端的随机位的先例,所以我可以更容易地编写测试

I'd hate to start a precedent of wrapping random bits of the backend so I can write tests more easily

我认为这是的究竟的先例,你需要设置!如果你的代码是不可测试的,你要继续努力进行测试。使其更易于测试,并增加你的覆盖面。

I think that's exactly the precedent you need to set! If your code isn't testable, you're going to keep struggling to test it. Make it easier to test, and increase your coverage.

这篇关于验证与起订量的参考参数的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆