我刚刚切换到Moq并遇到了问题.我正在测试一个创建业务对象的新实例的方法,从用户输入值设置对象的属性,并调用方法(SaveCustomerContact)来保存新对象.业务对象作为ref参数传递,因为它通过远程处理层.我需要测试传递给SaveCustomerContact的对象是否按预期设置了所有属性,但因为它在控制器方法中被实例化为new,所以我似乎无法这样做.
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 );
}
Run Code Online (Sandbox Code Playgroud)
这是测试:
[TestMethod()]
public void AddContactTest() {
int customerId = 0;
string name = "a";
var actual = new CustomerContact();
var expected = new CustomerContact() {
CustomerId = …
Run Code Online (Sandbox Code Playgroud) 我有一个使用输出参数的函数.我怎么能模仿这个功能?
我的功能是:
GetProperties(out string name, out string path, out string extension);
Run Code Online (Sandbox Code Playgroud)
在我的原始代码中,我这样做:
string Name;
string Path;
string Extension;
MyObject.GetProperties(out Name, out Path, out Extension);
Run Code Online (Sandbox Code Playgroud)
现在,我怎么能嘲笑这个?
我正在使用一个在函数中使用参数的库,我需要使用该函数测试我的代码.
所以,试图通过我在该项目的其他部分使用的Moq来嘲笑我.
我知道下面有一面墙,所以问题(提前)是:
我认为这是模拟IXLRow接口的嘲弄方面的问题.通常看起来XLRow只是从工作簿中实例化而从不通过new XLRow()
- 这是一个因素吗?
以下测试通过(注意:模拟):
[Fact]
public void TryGetValueCanReturnTrueForVieldWithAnInteger_WhenAccessingFromRow()
{
var workbook = new XLWorkbook();
workbook.Worksheets.Add("TestWS");
var wb = workbook.Worksheet("TestWS");
wb.Cell("A1").Value = "12345";
// NOTE: Here we're referring to the row as part of an instantiated
// workbook instead of Mocking it by itself
int output;
Assert.True(wb.Row(1).Cell("A").TryGetValue(out output));
}
Run Code Online (Sandbox Code Playgroud)
获取有效对象模拟的方法的片段():
// ...other code that sets up other parts of the row correctly
int isAnyInt = 0; //I don't care …
Run Code Online (Sandbox Code Playgroud) 对于像这样的方法:
protected virtual bool DoSomething(string str) { }
Run Code Online (Sandbox Code Playgroud)
我经常嘲笑它:
var mockModule = new Mock<MyClass> { CallBase = true };
mockModule.Protected().Setup<bool>("DoSomething", ItExpr.IsAny<string>()).Returns(true);
Run Code Online (Sandbox Code Playgroud)
但对于像这样的方法:
protected virtual bool DoSomething(out string str) { }
Run Code Online (Sandbox Code Playgroud)
我怎么嘲笑它?
提供的代码假定被模拟的函数返回一个值:
bool SomeFunc(out ISomeObject o);
Run Code Online (Sandbox Code Playgroud)
但是,我想要模拟的对象有一个out函数如下:
void SomeFunc(out ISomeObject o);
Run Code Online (Sandbox Code Playgroud)
来自上述答案的相关代码片段:
public delegate void OutAction<TOut>(out TOut outVal);
public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, TOut>(
this ICallback<TMock, TReturn> mock, OutAction<TOut> action)
where TMock : class
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
Void不是TReturn的有效类型.因此,我相信我必须以某种方式调整此代码,以使其与返回void的方法一起使用.但是怎么样?
我尝试使用NMock2但是在尝试将模拟传递给构造函数时我得到了TypeLoadExceptions,我也看到TypeMock可以做到这一点,但它花费80美元
我正在尝试使用Moq模拟以下方法签名的回调:
ResponseHeader AddIncentives(
Hs_transRow[] data,
out ResponseBody responseBody);
Run Code Online (Sandbox Code Playgroud)
我希望我的回调使用传入的数据。但是,我遇到的问题是因为第二个参数是out参数。我可以毫无问题地设置和返回数据,但是回调是一个问题。
这是我当前的设置:
var addIncentiveResponseBody = new ResponseBody();
mockCoinsService
.Setup(service => service.AddIncentives(It.IsAny<Hs_transRow[]>(), out addIncentiveResponseBody))
.Callback((Hs_transRow[] data, ResponseBody body) =>
{
//I want to use the data variable here
})
.Returns(() => new ResponseHeader
{
action = ResponseHeaderAction.RESPONSE,
});
Run Code Online (Sandbox Code Playgroud)
当我在单元测试中运行以下代码时,出现错误:
无效的回调。在具有参数(Hs_transRow [],ResponseBody&)的方法上进行的设置无法调用具有参数(Hs_transRow [],ResponseBody)的回调。
我可以看到&符之间的差异,我认为这是因为该参数应该是out参数。但是,如果将out关键字添加到回调中(并在回调中为其分配值),则会收到生成时间错误:
代表“动作”不带两个参数。
Moq是否无法处理具有out参数的方法的回调,还是我做错了什么?
[编辑]毫无疑问,我不是在问如何设置out参数的值。这行已经完成了:
var addIncentiveResponseBody = new ResponseBody();
Run Code Online (Sandbox Code Playgroud) 我在配置 Moq 时遇到了一些麻烦。
我有一个带有 out 参数的方法的模型。这个 out 参数真的被使用了,我需要根据我收到的参数用一些有意义的值填充它。
目前,我一直无法做到这一点,这可能吗?如何?
这是我目前的状态:
Mock<IMyMock> _mock = new Mock<IMyMock>();
bool someFlag= false;
_mock.Setup(m=>m.GetSomething(It.IsAny<DateTime>(), It.IsAny<DateTime>(), out someFlag))
.Returns((DateTime start, DateTime end, bool someFlagInternal)=>{
IEnumerable<SomeOtherClass> otherClasses = GenerateMockedData(start, end);
//Assign something to someFlag, depending on start and end
someFlag=true;//This has no effects
}) ;
new SomeController(_mock.Object);
Run Code Online (Sandbox Code Playgroud)
在我的SomeController
, 在特定方法上,我的真实非模拟代码调用它:
public class SomeController{}
private IMyMock _someObjectThatWeDontKnowIsAMock;
public SomeController(IMyMock someObjectThatWeDontKnowIsAMock) {
_someObjectThatWeDontKnowIsAMock= someObjectThatWeDontKnowIsAMock;
}
private void ComputeNext() {
Tuple<DateTime, DateTime> times = ComputeNextTimes();
bool hasOverlap;
IEnumerable<SomeOtherClass> otherClassesInstances …
Run Code Online (Sandbox Code Playgroud) 我有一个我正在测试的课程.此类使用接口中的take作为构造函数参数.此接口具有一个具有out参数的方法.
我想要做的是模拟这个方法,以便out参数始终是一个特定的值.
如何才能做到这一点?