【问题标题】:Why the method does not return custom exception message为什么该方法不返回自定义异常消息
【发布时间】:2019-02-04 21:34:58
【问题描述】:

我想要一个异步方法“UpdateAsync”在调用 PutAsync 方法时返回自定义异常消息。我现在要做的是模拟 PutAsync 所属的类,然后设置方法并提供参数。我还使用 Throws 来自定义异常消息。

问题是当我运行它时

var result = await this.repository.UpdateAsync(new EndPoint(new Uri(testUrl), HttpMethod.Put), JObject.FromObject(new object()), this.exceptionProcessor);

PutAsync 继续运行,没有返回异常。 这是代码。

Mock<RestClient> rc = new Mock<RestClient>();
rc.Setup(x => x.PutAsync(new Uri(testUrl), JObject.FromObject(new object()), new NameValueCollection()))
.Throws(new Exception("TestMessage"));

var result = await this.repository.UpdateAsync(new EndPoint(new Uri(testUrl), HttpMethod.Put), JObject.FromObject(new object()), this.exceptionProcessor);
Assert.IsTrue(result.ErrorMessages.GetValue(string.Empty).Equals("TestMessage"));

这里是UpdateAsync的主要部分,当进程到这里时,会先进入GetClient(),然后直接跳转到Exception。这个测试是用 Shimes 写的,但是我们不想再用 Shimes,所以我需要用另一种方式来做。

public virtual async Task<GenericOperationResult<object>> UpdateAsync(EndPoint endpoint, JContainer obj, IExceptionProcessor exceptionProcessor, NameValueCollection headers){

     if (endpoint.ActionMethod == HttpMethod.Put)
     {
        result = await this.GetClient().PutAsync(endpoint.Url, obj, headers);
     }
     else if (endpoint.ActionMethod == HttpMethod.Post)
     {
        result = await this.GetClient().PostAsync(endpoint.Url, obj, headers);
     }
     else
     {
        throw new ConfigurationException("Update supports only POST or PUT verbs. Check endpoint configuration.");
     }
     return new GenericOperationResult<object>(200, result); 
}

【问题讨论】:

  • 当设置期望与实际传递给模拟方法的内容不匹配时,调用时它不会按预期运行。
  • 您可能想要.Returns(Task.FromException(new Exception("TestMessage"))) 而不是Throws
  • @Lee 以你提供的方式显示无法将 Tasks.Task 转换为 Linq.JObject

标签: c# unit-testing mocking moq


【解决方案1】:

您在设置中实例化新对象,这些对象与您在调用 UpdateAsync 时实例化的对象不同,因此它们不会匹配,并且 Mock 对象不会引发异常。如果传入正确类型的对象,您可以改为设置模拟以引发异常,同时 Url 参数也检查它是否具有 testUrl,例如:

rc.Setup(x => x.PutAsync(It.Is<Uri>(u => u.OriginalString == testUrl), It.IsAny<JObject>(), It.IsAny<NameValueCollection>())
    .ThrowsAsync(new Exception("TestMessage"));

【讨论】:

  • 感谢重播。用你的方式更有意义。但是调用 PutAsync 时该过程仍然没有异常,这是 PutAsync , public virtual Task PutAsync(Uri uri, JContainer contentObject, NameValueCollection headers = null),我应该更改验证规则以使其被触发吗?跨度>
  • 啊,您应该使用 ThrowsAsync 而不是 Throws(代码已更新),尽管您可能需要确保您的 PutAsync 方法实际上被标记为异步。
  • PutAsync 是一个虚方法,public virtual Task PutAsync(Uri uri, JContainer contentObject, NameValueCollection headers = null)
  • 你能把虚拟方法签名改成异步的吗? (有可能:stackoverflow.com/questions/25015853/…)。如果不这样做,也许您可​​以提供所有代码。查看整个 UpdateAsync 方法会很有帮助。
  • 查看答案:codereview.stackexchange.com/questions/115928/… 在测试方法中注意模拟是如何传递到在其构造函数中测试的对象中的。
猜你喜欢
  • 2017-07-01
  • 1970-01-01
  • 2012-03-22
  • 2021-08-30
  • 1970-01-01
  • 2020-01-21
  • 2015-11-04
  • 2012-01-17
  • 1970-01-01
相关资源
最近更新 更多