I am building a system using Web API and Raven DB.
I am writing integration tests against the external boundary of this system.
public void GetAfterPostingPollReturnsPoll()
{
using (var client = HttpClientFactory.Create())
{
var poll = new
{
Question = "What is the answer?",
Options = new[] { "Yes", "No", "Maybe" }
};
var postResponse = client.PostAsJsonAsync("", poll).Result;
var pollLocation = postResponse.Headers.Location;
var getResponse = client.GetAsync(pollLocation).Result;
var actual = JsonConvert.DeserializeObject<Poll>(
getResponse.Content
.ReadAsStringAsync()
.Result);
Assert.Equal(poll.Question, actual.Question);
Assert.Equal(poll.Options, actual.Options);
}
}
When I submit an entry, the Controller interacts with a DocumentStore because that is how it works in production.
The trouble I am having is that the data produced in the test is never cleaned up.
Based on what I have been reading, I should use the EmbeddableDocumentStore for the purposes of my acceptance tests.
How might I use the DocumentStore normally but the EmbeddableDocumentStore when executing boundary tests like this one?
How do you "interact with DocumentStore" in your controller? The controller really only need to "interact" with the IDocumentSession that could be injected by the WebAPI infrastructure and in your integration test you register IDocumentStore to be implemented by EmbeddableDocumentStore (providing you use some kind of IoC container).
Related
I'm using ASP.NET Core with the ASP.NET API Versioning service.
When I register the service, I use this format:
services.AddVersionedApiExplorer(o => o.GroupNameFormat = "'v'VVV");
In an integration test, using the WebApplicationFactory:
var controller = nameof(CustomerController).Replace("Controller", "");
var action = nameof(CustomerController.SignIn);
var version = "v0"; // <------- the problem
var route = $"/api/${version}/${controller}/${action}";
var client = _factory.CreateClient();
var response = await client.GetAsync(route);
I don't want to hardcode version. Is it possible to get it from the test server somehow? Perhaps from the version service?
This can be retrieved from the container like so:
var version = _factory
.Services
.GetRequiredService<IApiVersionDescriptionProvider>()
.ApiVersionDescriptions
.Single() // if you have multiple versions, choose correct one
.GroupName;
Trying to write some integration tests for the first time in .NET - specifically for HotChocolate.
I’ve got had tests working with the WebApplicationFactory, the final part left is trying to now mock the authentication. I tried to set it up based on Mock Authentication but I’m querying the data with IRequestExecutor and finding the de-facto way of setting it up doesn't actually fire:
[Fact]
public async Task GetJokes()
{
var query =
#"query Jokes {
jokes(jokeLength: SMALL) {
nodes {
id
body
}
}
}";
var request = QueryRequestBuilder.New().SetQuery(query).Create();
var executor = await _factory.Services.GetRequestExecutorAsync();
var result = await executor.ExecuteAsync(request);
(await result.ToJsonAsync()).MatchSnapshot();
}
When I debug this I never hit HandleAuthenticateAsync in my AuthHandler’s (setup from the Mock Authentication linked above), so the claims are never added - so looks like those only run for the httpClient requests - is there a way to configure the IRequestExecutor to be authenticated too?
You can add the ClaimsPrincipal directly as property to the QueryRequestBuilder.
var request = QueryRequestBuilder
.New()
.SetQuery(query)
.AddProperty(nameof(ClaimsPrincipal), new ClaimsPrincipal(new ClaimsIdentity("test")))
.Create();
How can I test in asp.net core 2.0 following method which exists in separate project than my test project? for example like this:
public partial class LoanRequestServiceController : BaseServiceController
{
public ServiceDTO<AP_CBO> AddCBO(AP_CBO cbo)
{
ServiceDTO<AP_CBO> dto = new ServiceDTO<AP_CBO>();
try
{
using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Snapshot }))
{
cbo.ID_CBO = 333;
dto.Data = cbo;
scope.Complete();
}
}
catch (Exception ex)
{
dto.Error = new ServiceError(ex);
Globals.Logger.Error(ex);
}
finally
{
//Globals.CastleComponentsContainer.Release(LoanRequestDAL);
}
return dto;
}
}
I tested some "light" methods such as if service method returns SucessCode and it works.
Here is my test class:
[Theory]
[InlineData("/Sample/AddCBO")]
public async Task Test_AddCBO(string url)
{
//Arrange
var client = _factory.CreateClient();
//Act
var response = await client.GetAsync(url);
//Assert
response.EnsureSuccessStatusCode();
//Compare two dto objects AP_CBO
//object expected = new AP_CBO { properties... }
// object responseObject = response.Content...
//Assert.Equal(expected, responseObject);
}
I don't know how to test an object with muliple properties.
Maybe I need to use Moq? Theoretically, this method would be go to the DAL (DatabaseAccess Layer) and return from database packed object and returns to the api, or in my case back into test.
First off, you have to decide which level of tests you want to write.
If you're writing a Unit test, you should mock any and all external integrations (in your case I can identify HTTP request -> Controller and Controller -> Database). This is the foundation of your functional testing. So if you're writing unit tests, yes, you should use a mocking framework such as NSubstitute or Moq (and only test your method's behavior by calling it).
The test sample you posted looks to me like an integration test since you're including the integration HTTP request -> Controller. In this case I would seed the database with data (if relevant) and actually call your API endpoint (as you're already doing).
To check the content (DTO) of the response in ASP.Net Core you have to do the following:
// ...
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var content = await httpResponseMessage.Content.ReadAsStringAsync();
var serviceDto = JsonConvert.DeserializeObject<ServiceDTO<AP_CBO>>(content); // Only for Json
// Validate serviceDto
It is pretty long topic for detailed explanation here ; i think it will be better if you follow a sample and read the details.
I assume that you are going to write unit test; for unit test i can recommend this tutorial that may help you . check this please
I would like to unit test my ValidationFeature rulesets in my ServiceStack project however the plugin is not being initialized when creating my appHost object.
Here is my original code to initialize the appHost.
[TestFixtureSetUp]
private void TestFixtureSetUp()
{
appHost = new BasicAppHost().Init();
appHost.Plugins.Add(new ValidationFeature());
var container = appHost.Container;
container.RegisterValidators(typeof(ApplicationValidator).Assembly);
container.RegisterAutoWiredAs<FakeRetailReferralRepository, IRetailReferralRepository>();
container.RegisterAutoWired<SubmitApplicationService>();
}
I've tried moving the Plugins.Add line in between the BasicAppHost constructor and Init() and that didn't work either. Is what I'm trying to do possible?
The validation feature is validated within the Request Pipeline so would typically require a full integration test to test it, i.e. using a self-host and service client.
You can still unit test a validator, but as validation occurs before the Service is called you would need to test the validator with the Request DTO directly instead of calling the Service, e.g:
using (var appHost = new BasicAppHost
{
ConfigureAppHost = host => {
host.Plugins.Add(new ValidationFeature());
},
ConfigureContainer = c => {
c.RegisterValidators(typeof(ApplicationValidator).Assembly);
}
}.Init())
{
var myValidator = appHost.TryResolve<IValidator<MyRequest>>();
var result = myValidator.Validate(new MyRequest { ... });
Assert.That(result.IsValid, Is.False);
Assert.That(result.Errors.Count, Is.EqualTo(1));
}
So my problem is as follows...for a project we are bulding an api using RavenDb and Nancy. So my question is about unit testing...we use embeded db, which runs in memory as suggested many times. , how to proper unit test end points. For example, we have a endpoint create account. For that we need to have a user so he can create account. What is the best way to simulate that?
Currently we do it like this:
[Test]
public void UserCanAddAccountToCompany()
{
var user =
new User
{
Name = Guid.NewGuid().ToString(),
Email = Guid.NewGuid().ToString(),
Pwd = "password",
CompanyReference = new CompanyReference { Id = Guid.NewGuid().ToString(), Name = Guid.NewGuid().ToString() }
};
var response = new TestBrowser<User>("User/SignUp", user).Response;
var paramUserAccount = new ParamUserAccount()
{
User = response.Body.DeserializeJson<Result>().User,
Account = new Account() { Name = Guid.NewGuid().ToString() }
};
var response2 = new TestBrowser<ParamUserAccount>("account/create", paramUserAccount).Response;
var res = response2.Body.DeserializeJson<Result>();
Assert.NotNull(res.Account.Id);
Assert.NotNull(res.Account.Name);
}
So we create a user , call user signup end point and then take the params from response and call creat accoutn end point. The obvious problem with this approach is that if you do a change in signup endpoint and for some reason you break it, all tests like this will fail.
So my question is...what's the right approach on that?
You are intergration testing, not unit testing. To properly unit test, you need to test without the db by using mocking objects.