gpt4 book ai didi

c# - 使用 Moq 验证引用参数的值

转载 作者:IT王子 更新时间:2023-10-29 04:47:09 32 4
gpt4 key购买 nike

我刚刚切换到最小起订量并遇到了问题。我正在测试一种创建业务对象的新实例的方法,根据用户输入值设置对象的属性并调用方法 (SaveCustomerContact) 来保存新对象。业务对象作为 ref 参数传递,因为它通过远程处理层。我需要测试传递给 SaveCustomerContact 的对象是否按预期设置了所有属性,但因为它在 Controller 方法中被实例化为新对象,所以我似乎无法这样做。

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();

}

这只是获取该参数的许多尝试中的最新一次。作为引用,actual 的值不会从其初始(构造)状态改变。

在目标调用失败后移动 Assert.AreEqual(expected, actual)。如果我将 .Verifiable() 添加到设置而不是 .CallBack,然后在目标之后调用 remote.Verify(或者,我假设,将模拟设置为严格)它总是失败,因为我在测试中提供的参数不是与在 Controller 方法中创建的实例相同。

我使用的是最小起订量 3.0.308.2。任何关于如何测试这个的想法将不胜感激。谢谢!

最佳答案

我无法为您提供确切的解决方案,但另一种方法是将传递引用语义隐藏在适配器后面,它按值获取参数并将其转发给 RemotingHandler。这会更容易模拟,并且会从界面中删除“ref”疣(我总是怀疑 ref 参数 :-))

编辑:

或者您可以使用 stub 而不是模拟,例如:

public class StubRemotingHandler : IRemotingHandler
{
public CustomerContact savedContact;

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

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

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

我认为这正是您需要树立的先例!如果您的代码不可测试,您将继续努力测试它。使测试更容易,并增加覆盖率。

关于c# - 使用 Moq 验证引用参数的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/726630/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com