Недавно я начал изучать, как писать модульные тесты, а также какую часть модуля тестировать на функциональность и что издеваться. Я использую NSubstitute как свою насмешливую структуру. Мой пример в основном вызывает класс repo, который затем делает веб-вызов WEB API внешней службе, то есть AddCreditCard, которая затем возвращает результат. Я создал 2 модульных теста для AddCreditCard, один для успеха и один для Fail. Я все еще не на 100% уверен, что все правильно делаю. Единичные тесты проходят, но я не уверен, что мои проверки сделаны на правильные данные ... Вся помощь и предложения приветствуются!Я правильно пишу свои модульные тесты? NUnit + NSubstitute
public interface IApiResponse<T>
{
HttpStatusCode StatusCode { get; set; }
T Result { get; set; }
string ErrorMessage { get; }
bool HasErrors { get; }
}
public interface ISignedRequest
{
void ConfigureSettings(SignedRequestSettings settings);
IApiResponse Post(string jsonData, Dictionary<string, string> parameters = null,
IOptionalHeaders optionalHeaders = null);
}
public class PaymentRepository
{
private readonly SignedRequestSettings _settings;
private readonly ISignedRequest _signedRequest;
public PaymentRepository(ISignedRequest signedRequest = null)
{
if (signedRequest == null)
_signedRequest = new SignedRequest();
else
_signedRequest = signedRequest;
}
public IApiResponse AddCreditCard(CreditCard request)
{
var jsonData =
JsonConvert.SerializeObject(request);
string action = string.Format("customers/{0}/paymentmethods", request.ConnectId);
_settings.Url = string.Format("{0}{1}", String.Empty, action);
_signedRequest.ConfigureSettings(_settings);
return _signedRequest.Post(jsonData);
}
}
[Test]
public void AddCreditCard_GivenValidCreditCard_ReturnsCreatedResult()
{
//Given
var apiResponse = Substitute.For<IApiResponse>();
apiResponse.StatusCode = HttpStatusCode.Created;
var signedRequest = Substitute.For<ISignedRequest>();
signedRequest.Post(Arg.Any<String>()).Returns(apiResponse);
var creditCard = Substitute.For<CreditCard>();
creditCard.ConnectId = Guid.Parse("1fc1ad83-cd4e-4b68-bce6-e03ee8f47fb6");
var repo = new PaymentRepository(signedRequest);
//When
var addCreditCardResponse = repo.AddCreditCard(creditCard);
//Then
signedRequest.Received(1).ConfigureSettings(Arg.Any<SignedRequestSettings>());
signedRequest.Received(1).Post(Arg.Any<String>());
Assert.AreEqual(HttpStatusCode.Created, addCreditCardResponse.StatusCode);
}
[Test]
public void AddCreditCard_GivenInvalidCreditCard_ReturnsHasErrorsResult()
{
//Given
var apiResponse = Substitute.For<IApiResponse>();
apiResponse.HasErrors.Returns(true);
apiResponse.ErrorMessage.Returns("Add credit card error message");
var signedRequest = Substitute.For<ISignedRequest>();
signedRequest.Post(Arg.Any<String>()).Returns(apiResponse);
var creditCard = Substitute.For<CreditCard>();
creditCard.ConnectId = Guid.Parse("1fc1ad83-cd4e-4b68-bce6-e03ee8f47fb6");
var repo = new PaymentRepository(signedRequest);
//When
var addCreditCardResponse = repo.AddCreditCard(creditCard);
//Then
signedRequest.Received(1).ConfigureSettings(Arg.Any<SignedRequestSettings>());
signedRequest.Received(1).Post(Arg.Any<String>());
Assert.AreEqual(apiResponse.HasErrors, addCreditCardResponse.HasErrors);
Assert.AreEqual(apiResponse.ErrorMessage, addCreditCardResponse.ErrorMessage);
}
На первом румянце они выглядят как большие юнит-тесты. Одно из предложений, которое я хотел бы использовать, - использовать определенные аргументы или [сопоставление аргументов] (http://nsubstitute.github.io/help/argument-matchers/) в ваших 'signedRequest.Received (1)' вызовах. Если эти значения не важны для того, что вы тестируете. –