zip方法中出现意外行为

时间:2017-07-14 13:34:34

标签: c# linq unit-testing

我有以下代码:

public getData(url: string): Observable<any> {
    let cachedData = this.cacheService.get(url);

    return cachedData
        ? Observable.of(cachedData)
        : this.http.get(url)
            .map(res => res.json())
            .map(res => {
                // Save the data in the cache for the next time
                this.cacheService.set(url, res);
                return res;
            });
}

我预计我的测试会失败,但会成功通过。我真的想知道这怎么可能?如下所示,[TestMethod()] public void Test_Changed() { var All = repository.GetProducts().Select(c => c.Price).ToList(); var Original = All.ToList(); //The following line updates all prices but should has no effect //Because I've used ToList already in All query reducer.ReducePrice(amount); All.Zip(Original, (f, s) => { if (f == s) { Assert.Fail(); } return f; }); } All变量具有相同的值,为什么Original从未执行?

enter image description here

如果我从Assert.Fail();查询中删除ToList,则测试应该按预期传递,因为延迟执行但是当我使用All时,后面的更改应该没有效果。那么为什么我的测试通过?

请同时看到:

ToList

结果:

enter image description here

但是测试结果:

enter image description here

2 个答案:

答案 0 :(得分:7)

与许多LINQ操作一样,Zip是懒惰的 - 你的lambda表达式永远不会被执行,因为你正在调用Zip但从不使用结果。

如果您将测试更改为:

var list = All.Zip(...).ToList();

然后我怀疑你会看到断言失败。 (或者调用Count(),或者在整个序列上迭代的任何其他内容。)

或者像Jamiec所说,添加一个断言。它可以很简单:

Assert.IsFalse(All.Zip(Original, (f, s) => f == s).Any(x => x));

(这实际上取决于您尝试检查的内容 - 不同的断言会为您提供不同类型的信息。)

答案 1 :(得分:0)

如果您找到匹配对并且如果找不到任何测试就失败,那么您的测试会更好

var result = All.Zip(Original, (f, s) =>
    {            
        return f == s;
    });
Assert.IsFalse(result.Where(x => x).Any());
// or: Assert.IsFalse(result.Any(x => x));