最近在做单元测试,途中发现一个很蛋疼的问题。
总所周知,我可以通过Setup去选择一个方法,然后ReturnsAsync可以返回这个方法所需要的返回参数。
可是,今天我碰到一个问题,ReturnsAsync无论如何都不起作用,调试了半天发现是因为方法的返回参数是 Expression<Func<T, bool>>。我在Setup里面写着
x => x.GetMany(s => s.TDPId == It.IsAny<int>())
可是无论我怎么调用这个方法,返回数据永远都是Count = 0,可是当我把参数改为固定值后返回参数便可以用了。
请问各位大神,是我写的方式不对。。还是单元测试不支持lambda表达式?
已解决,需要把mock的方法改为
this._itapLoginSessionRepository.Setup(x => x.GetList(It.IsAny<Expression<Func<ItapLoginSession,bool>>>())) .Returns(itapLoginSessions).Verifiable();
moq的setup支持lambda,但看不到来你完整的写法。
首先,我在逻辑处理层中,方法中有这么一段代码,是用来获取数据
var loginSessions = await this._itapLoginSessionRepository.GetList(s => s.TdpId == tdpId);
其次,我在单元测试中,对这个方法进行了mock
private Mock<IItapLoginSessionRepository> _itapLoginSessionRepository; [TestInitialize] public void Initialize() { this._itapLoginSessionRepository = new Mock<IItapLoginSessionRepository>(); this._itapLoginSessionRepository.Setup(x => x.GetList(s => s.TdpId == It.Any<int>())) .ReturnsAsync(itapLoginSessions); }
可是,我在调试单元测试的时候,发现loginSessions返回的数据总是null
itapLoginSessions的数据为
private List<ItapLoginSession> itapLoginSessions; List<ItapLoginSession> itapLoginList = new List<ItapLoginSession>(); for (int i = 0; i < 1; i++) { itapLoginList.Add(new ItapLoginSession() { Id = i + 1, TDPId = 666666, SessionId = 2 + i, IsLogoutSession = i % 2 > 0, TDPName = "这是第" + i + "条数据" }); } itapLoginSessions = itapLoginList;
@临冰听雪丶:
.ReturnAsync(()=>getLoginSession());
我觉得应该是这样的吧,你下面的代码中由于有缺失,现在只能主观判断为itapLoginSessions根本没赋值。
ps下,刚才查了下ReturnAsync方法之前版本有bug,对应的委托方法只会执行一次,可能需要使用Return+Task.FromResult去绕
@Daniel Cai: 您的意思是说ReturnAsync里面传入一个直接返回的方法吗?
我的itapLoginSessions是赋值过的。它在Initialize里,我这里忘了把那个方法加进去了,sorry。。。
至于您最后说的那个bug,我没太懂,“Return+Task.FromResult去绕”我该如何去按您说的绕呢?
@临冰听雪丶: ReturnAsync方法的bug是只会在setup运行一次,但很多场景下是需要做不同的返回,但Return方法没有这个bug,所以使用这种方式去绕开这个bug。当然这个bug是之前的了,不知道现在修正了没。
@Daniel Cai: 噢,这个啊,我目前还没有发现呢,不过,谢谢您啦~