Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#最低起订量-嘲弄行为<;T>;参数_C#_Unit Testing_Action_Moq - Fatal编程技术网

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;
}