C#最低起订量-嘲弄行为<;T>;参数
我已经绞尽脑汁搞了一段时间了,我想从你那里得到一些帮助,谢谢你的帮助 基本代码 例如,我创建了两种消息类型:C#最低起订量-嘲弄行为<;T>;参数,c#,unit-testing,action,moq,C#,Unit Testing,Action,Moq,我已经绞尽脑汁搞了一段时间了,我想从你那里得到一些帮助,谢谢你的帮助 基本代码 例如,我创建了两种消息类型: public class RefreshMessage : MessageBase { } public class CancelMessage : MessageBase { } 在代码的某些部分中,消息有两个订阅 ... MessageHub.Subscribe<RefreshMessage>("Refresh", RefreshMethod); MessageHub
public class RefreshMessage : MessageBase { }
public class CancelMessage : MessageBase { }
在代码的某些部分中,消息有两个订阅
...
MessageHub.Subscribe<RefreshMessage>("Refresh", RefreshMethod);
MessageHub.Subscribe<CancelMessage>("Cancel", CancelMethod);
...
这些部分是由框架提供的,因此我无法更改它们
单元测试
在单元测试中,我想用Moq模拟MessageHub,为每个操作模拟Subscribe方法,并获取调用Subscribe方法的回调方法
通常,我必须为每个消息类型创建2个设置,如下所示:
var messageHubMock = new Mock<IMessageHub>();
var methods = new List<dynamic>();
//setup for RefreshMessage
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<RefreshMessage>>())
.Callback<string,Action<RefreshMessage>>((s,a)=> methods.Add(a));
//setup for CancelMessage
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<CancelMessage>>())
.Callback<string,Action<CancelMessage>>((s,a)=> methods.Add(a));
var messageHubMock=new Mock();
var方法=新列表();
//刷新消息的设置
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
//取消消息的设置
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
设置问题
问题是,如何在1个设置中进行2个设置
以下设置不起作用,但表明我已经尝试过了
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<object>>())
.Callback<string,Action<object>>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<dynamic>>())
.Callback<string,Action<dynamic>>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<object>())
.Callback<string,object>((s,a)=> methods.Add(a));
//does not compile
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action>())
.Callback<string,Action>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<MessageBase>>())
.Callback<string,Action<MessageBase>>((s,a)=> methods.Add(a));
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
//不编译
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
messageHubMock.Setup(\u=>\ uu.Subscribe(It.IsAny,It.IsAny())
.Callback((s,a)=>methods.Add(a));
所有这些都不适合表达式,因此即使在代码中调用了subscibre,Moq也不会在安装程序上运行回调,因为subscribe是使用“不同”参数调用的
我想我需要在此基础上创建自己的表达式过滤器逻辑。
你能帮助我,如何创建这个设置,只有一个设置吗?有时候Moq总是最适合这个工作的工具。试着用一个简单的存根来代替。我仍然在寻找一种在Moq中实现它的方法,但现在应该可以了
[TestClass]
public class UnitTest {
[TestMethod]
public void _Mock_Action_T_Without_Moq() {
//Arrange
var callbacks = new Dictionary<string, dynamic>();
var messageHubMock = new MessageHubStub(callbacks);
//Act
var sut = new Sut(messageHubMock.Object);
//Assert
Assert.IsTrue(callbacks.Count == 2);
Assert.IsNotNull(callbacks["Refresh"]);
Assert.IsNotNull(callbacks["Cancel"]);
}
public class Sut {
public Sut(IMessageHub MessageHub) {
MessageHub.Subscribe<RefreshMessage>("Refresh", RefreshMethod);
MessageHub.Subscribe<CancelMessage>("Cancel", CancelMethod);
}
private void CancelMethod(CancelMessage obj) {
throw new NotImplementedException();
}
private void RefreshMethod(RefreshMessage obj) {
throw new NotImplementedException();
}
}
public class MessageHubStub : IMessageHub {
private Dictionary<string, dynamic> callbacks;
public MessageHubStub(Dictionary<string, dynamic> callbacks) {
this.callbacks = callbacks;
}
public IMessageHub Object { get { return this; } }
public void Subscribe<T>(string topic, Action<T> callback) {
callbacks.Add(topic, callback);
}
}
public interface IMessageHub {
void Subscribe<T>(string topic, Action<T> callback);
}
public class MessageBase { }
public class RefreshMessage : MessageBase { }
public class CancelMessage : MessageBase { }
}
好问题。乍一看,每个设置似乎都覆盖了前一个设置。感谢您的回复,但遗憾的是,我无法修改IMessageHub,我需要使用Moq模拟类。我需要在一行中设置两个函数,以便对每个订阅都进行回调。然后不要更改hub。用一个假函数替换它以进行测试。这就是您要解决的问题不管怎么说,我还是要用最小起订量。
var messageHubMock = new Mock<IMessageHub>();
var methods = new List<dynamic>();
//setup for RefreshMessage
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<RefreshMessage>>())
.Callback<string,Action<RefreshMessage>>((s,a)=> methods.Add(a));
//setup for CancelMessage
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<CancelMessage>>())
.Callback<string,Action<CancelMessage>>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<object>>())
.Callback<string,Action<object>>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<dynamic>>())
.Callback<string,Action<dynamic>>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<object>())
.Callback<string,object>((s,a)=> methods.Add(a));
//does not compile
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action>())
.Callback<string,Action>((s,a)=> methods.Add(a));
messageHubMock.Setup(_=>_.Subscribe(It.IsAny<string>,It.IsAny<Action<MessageBase>>())
.Callback<string,Action<MessageBase>>((s,a)=> methods.Add(a));
[TestClass]
public class UnitTest {
[TestMethod]
public void _Mock_Action_T_Without_Moq() {
//Arrange
var callbacks = new Dictionary<string, dynamic>();
var messageHubMock = new MessageHubStub(callbacks);
//Act
var sut = new Sut(messageHubMock.Object);
//Assert
Assert.IsTrue(callbacks.Count == 2);
Assert.IsNotNull(callbacks["Refresh"]);
Assert.IsNotNull(callbacks["Cancel"]);
}
public class Sut {
public Sut(IMessageHub MessageHub) {
MessageHub.Subscribe<RefreshMessage>("Refresh", RefreshMethod);
MessageHub.Subscribe<CancelMessage>("Cancel", CancelMethod);
}
private void CancelMethod(CancelMessage obj) {
throw new NotImplementedException();
}
private void RefreshMethod(RefreshMessage obj) {
throw new NotImplementedException();
}
}
public class MessageHubStub : IMessageHub {
private Dictionary<string, dynamic> callbacks;
public MessageHubStub(Dictionary<string, dynamic> callbacks) {
this.callbacks = callbacks;
}
public IMessageHub Object { get { return this; } }
public void Subscribe<T>(string topic, Action<T> callback) {
callbacks.Add(topic, callback);
}
}
public interface IMessageHub {
void Subscribe<T>(string topic, Action<T> callback);
}
public class MessageBase { }
public class RefreshMessage : MessageBase { }
public class CancelMessage : MessageBase { }
}
public interface IMessageHub {
void Subscribe<T>(string topic, Action<T> callback) where T : MessageBase;
}