这是var pos = Player.getBoundingClientRect();
var BeginningPos = pos.x;
内的Action方法示例:
HomeController
我想测试一下,但我不知道怎么做。我尝试了以下方法:
[HttpPost]
public async Task<dynamic> UnitTest(string data)
{
var httpClient = new HttpClient();
var request = JsonConvert.SerializeObject(data);
var url = "https://jsonplaceholder.typicode.com/posts";
var response = await httpClient.PostAsync(url, new StringContent(request, Encoding.UTF8, "application/json"));
string responseContent = await response.Content.ReadAsStringAsync();
return responseContent;
}
不幸的是,上述方法无效。由于我很困惑,你可以给我一些以下答案:
[TestMethod]
public async Task JsonRightTest()
{
MyModelR model1 = new MyModelR
{
Title = "foo",
Body = "bar",
UserId = 1
};
string output1 = JsonConvert.SerializeObject(model1);
var url = "Home/UnitTest";
var response = await _client.PostAsync(url, new StringContent(output1, Encoding.UTF8, "application/json"));
response.EnsureSuccessStatusCode();
var responseContent = await response.Content.ReadAsStringAsync();
var responseModel = JsonConvert.DeserializeObject<MyModel>(responseContent);
// Assert
Assert.AreEqual(1,
responseModel.UserId);
}
internal class MyModel
{
public string Title { get; set; }
public string Body { get; set; }
public int UserId { get; set; }
public int Id { get; set; }
}
internal class MyModelR
{
public string Title { get; set; }
public string Body { get; set; }
public int UserId { get; set; }
}
行动的最佳方法是什么?我的方法有误吗? 我是否只需要从JsonRightTest方法调用API而不涉及操作?UnitTest
或unit
测试?我想调用实际的外部终点。
API(https://jsonplaceholder.typicode.com/posts)可在Internet上找到,可用于测试目的。
答案 0 :(得分:2)
这似乎是一个XY problem和一系列问题。
正在测试的代码与实现问题紧密相关,应该将外部调用封装在服务抽象之后,可以在隔离的单元测试中进行模拟。
应该遵循的一些重构步骤......
在测试中构建的那些模型应该在行动中。
[HttpPost]
public async Task<IActionResult> UnitTest([FromBody]MyDataR data) {
var httpClient = new HttpClient();
var requestJson = JsonConvert.SerializeObject(data);
var url = "https://jsonplaceholder.typicode.com/posts";
var response = await httpClient.PostAsync(url, new StringContent(requestJson, Encoding.UTF8, "application/json"));
if(response.IsSuccessStatusCode) {
var responseContent = await response.Content.ReadAsStringAsync();
var responseModel = JsonConvert.DeserializeObject<MyModel>(responseContent);
return Ok(responseModel);
}else
return StatusCode(response.StatusCode);
}
进一步重构,应该抽象出外部端点的实际调用
public interface IExternalService {
Task<MyModel> PostDataAsync(MyData data);
}
并相应地实施
public class ExternalService : IExternalService {
// should consider abstracting this as well but that is another matter
static Lazy<HttpClient> _httpClient = new Lazy<HttpClient>(() => new HttpClient());
private HttpClient httpClient {
get { return _httpClient.Value; }
}
public async Task<MyModel> PostDataAsync(MyData data) {
var requestJson = JsonConvert.SerializeObject(data);
var url = "https://jsonplaceholder.typicode.com/posts";
var content = new StringContent(requestJson, Encoding.UTF8, "application/json")
var response = await httpClient.PostAsync(url, content);
var responseContent = await response.Content.ReadAsStringAsync();
if(response.IsSuccessStatusCode) {
var responseContent = await response.Content.ReadAsStringAsync();
var responseModel = JsonConvert.DeserializeObject<MyModel>(responseContent);
return responseModel;
}else
return null;
}
}
控制器中的操作现在看起来像
private readonly IExternalService externalService; // Assumed injected into the controller
[HttpPost]
public async Task<IActionResult> UnitTest([FromBody]MyDataR data) {
var responseModel = await externalService.PostDataAsync(data);
if(responseModel != null) {
return Ok(responseModel);
}else
return BadRequest();
}
通过删除与外部服务调用的紧耦合,这将允许根据需要单独测试控制器,以验证其行为符合预期。
如果希望检查外部端点是否按预期运行,现在可以自行测试外部服务调用实现。由于它依赖于实际的外部端点,因此将被视为集成测试。
[TestMethod]
public async Task JsonRightTest() {
// Arrange
var expected = 1;
var model = new MyModelR {
Title = "foo",
Body = "bar",
UserId = 1
};
var target = new ExternalService(); // System under test
// Act
var responseModel = await target.PostDataAsync(model);
// Assert
Assert.IsNotNull(responseModel);
var actual = responseModel.UserId;
Assert.AreEqual(expected, actual);
}
现在应该可以更容易地检查外部服务,以验证它是否按预期运行。
在生产中,您将确保外部服务抽象及其实现在组合根中注册。
services.AddTransient<IExternalService, ExternalService>();
以便正确地将其注入从属控制器。