Skip to content

Commit

Permalink
Feature/add unit test to blazor (#329)
Browse files Browse the repository at this point in the history
* Add blazor unit test to device list page

* Fix unit test

* Fix internal visibles to for unit tests

* Change test artifacts directory
  • Loading branch information
kbeaugrand authored Feb 25, 2022
1 parent 0a701fc commit b9fdcdf
Show file tree
Hide file tree
Showing 29 changed files with 501 additions and 34 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
path: ./src/swagger.json

- name: Run unit tests
run: dotnet test --no-build --verbosity normal --logger trx --collect:"XPlat Code Coverage" /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura AzureIoTHub.Portal.Server.Tests/AzureIoTHub.Portal.Server.Tests.csproj
run: dotnet test --no-build --verbosity normal --logger trx --collect:"XPlat Code Coverage" /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura AzureIoTHub.Portal.Server.Tests.Unit/AzureIoTHub.Portal.Server.Tests.Unit.csproj
working-directory: src/

# Upload test results as artifact
Expand All @@ -54,12 +54,12 @@ jobs:
with:
name: test-results
path: |
src/AzureIoTHub.Portal.Server.Tests/TestResults
src/AzureIoTHub.Portal.Server.Tests.Unit/TestResults
- name: Upload to Codecov test reports
uses: codecov/codecov-action@v2
with:
directory: src/AzureIoTHub.Portal.Server.Tests/TestResults
directory: src/AzureIoTHub.Portal.Server.Tests.Unit/TestResults

add-openapi-docs:
name: Import OpenAPI to documentation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="bunit" Version="1.5.12" />
<PackageReference Include="bunit.core" Version="1.5.12" />
<PackageReference Include="bunit.web" Version="1.5.12" />
<PackageReference Include="bunit.web.testcomponents" Version="1.5.12" />
<PackageReference Include="FluentAssertions" Version="6.5.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
Expand All @@ -17,6 +21,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="RichardSzalay.MockHttp" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
using AzureIoTHub.Portal.Server.Controllers.V10.LoRaWAN;
using AzureIoTHub.Portal.Server.Managers;
using AzureIoTHub.Portal.Server.Mappers;
using AzureIoTHub.Portal.Server.Services;
using AzureIoTHub.Portal.Shared.Models.V10.LoRaWAN.Concentrator;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AzureIoTHub.Portal.Server.Tests.Controllers.V10
{
[TestFixture]
public class ConcentratorsControllerTests
{
private MockRepository mockRepository;

private Mock<IRouterConfigManager> mockRouterManager;
private Mock<IConcentratorTwinMapper> mockConcentratorTwinMapper;
private Mock<IDeviceService> mockDeviceService;
private Mock<ILogger<LoRaWANConcentratorsController>> mockLogger;

[SetUp]
public void SetUp()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);

this.mockLogger = this.mockRepository.Create<ILogger<LoRaWANConcentratorsController>>();
this.mockRouterManager = this.mockRepository.Create<IRouterConfigManager>();
this.mockConcentratorTwinMapper = this.mockRepository.Create<IConcentratorTwinMapper>();
this.mockDeviceService = this.mockRepository.Create<IDeviceService>();
}

private LoRaWANConcentratorsController CreateController()
{
return new LoRaWANConcentratorsController(
this.mockLogger.Object,
this.mockDeviceService.Object,
this.mockRouterManager.Object,
this.mockConcentratorTwinMapper.Object);
}

[Test]
public async Task GetAllDeviceConcentrator_WithNoArgument_ReturnConcentratorList()
{
// Arrange
var twin = new Twin("aaa");
twin.Tags["deviceType"] = "LoRa Concentrator";
var concentrator = new Concentrator
{
DeviceId = twin.DeviceId,
DeviceType = "LoRa Concentrator"
};

this.mockDeviceService.Setup(x => x.GetAllDevice(
It.Is<string>(x => x == "LoRa Concentrator"),
It.Is<string>(x => string.IsNullOrEmpty(x))))
.ReturnsAsync(new[]
{
twin
});

this.mockConcentratorTwinMapper.Setup(x => x.CreateDeviceDetails(It.Is<Twin>(c => c.DeviceId == twin.DeviceId)))
.Returns(concentrator);

var concentratorController = this.CreateController();

// Act
var response = await concentratorController.GetAllDeviceConcentrator();

// Assert
Assert.IsNotNull(response);
Assert.IsAssignableFrom<OkObjectResult>(response.Result);
var okObjectResult = response.Result as ObjectResult;

Assert.IsNotNull(okObjectResult);
Assert.AreEqual(200, okObjectResult.StatusCode);
Assert.IsNotNull(okObjectResult.Value);
var deviceList = okObjectResult.Value as IEnumerable<Concentrator>;
Assert.IsNotNull(deviceList);
Assert.AreEqual(1, deviceList.Count());
var device = deviceList.First();
Assert.IsNotNull(device);
Assert.AreEqual(twin.DeviceId, device.DeviceId);
Assert.AreEqual("LoRa Concentrator", device.DeviceType);

this.mockRepository.VerifyAll();
}

[Test]
public async Task GetDeviceConcentrator_With_Valid_Argument_Should_Return_Concentrator()
{
// Arrange
var twin = new Twin("aaa");
twin.Tags["deviceType"] = "LoRa Concentrator";
var concentrator = new Concentrator
{
DeviceId = twin.DeviceId,
DeviceType = "LoRa Concentrator"
};

this.mockDeviceService.Setup(x => x.GetDeviceTwin(It.Is<string>(c => c == twin.DeviceId)))
.ReturnsAsync(twin);

this.mockConcentratorTwinMapper.Setup(x => x.CreateDeviceDetails(It.Is<Twin>(c => c.DeviceId == twin.DeviceId)))
.Returns(concentrator);

var concentratorController = this.CreateController();

// Act
var response = await concentratorController.GetDeviceConcentrator(twin.DeviceId);

// Assert
Assert.IsNotNull(response);
Assert.IsAssignableFrom<OkObjectResult>(response.Result);
var okObjectResult = response.Result as OkObjectResult;

Assert.IsNotNull(okObjectResult);
Assert.AreEqual(200, okObjectResult.StatusCode);
Assert.IsNotNull(okObjectResult.Value);
Assert.IsAssignableFrom<Concentrator>(okObjectResult.Value);
var device = okObjectResult.Value as Concentrator;
Assert.IsNotNull(device);
Assert.AreEqual(twin.DeviceId, device.DeviceId);
Assert.AreEqual("LoRa Concentrator", device.DeviceType);

this.mockRepository.VerifyAll();
}

[Test]
public async Task CreateDeviceAsync_With_Valid_Argument_Should_Return_OkResult()
{
// Arrange
var concentratorController = this.CreateController();
var concentrator = new Concentrator
{
DeviceId = "4512457896451156",
LoraRegion = Guid.NewGuid().ToString(),
IsEnabled = true
};

var routerConfig = new RouterConfig();
var mockResult = new BulkRegistryOperationResult
{
IsSuccessful = true
};

var twin = new Twin
{
DeviceId = concentrator.DeviceId,
};

this.mockDeviceService.Setup(c => c.CreateDeviceWithTwin(
It.Is<string>(x => x == twin.DeviceId),
It.Is<bool>(x => !x),
It.Is<Twin>(x => x.DeviceId == twin.DeviceId),
It.Is<DeviceStatus>(x => x == DeviceStatus.Enabled)))
.ReturnsAsync(mockResult);

this.mockRouterManager.Setup(x => x.GetRouterConfig(It.Is<string>(c => c == concentrator.LoraRegion)))
.ReturnsAsync(routerConfig);

this.mockConcentratorTwinMapper.Setup(x => x.UpdateTwin(It.Is<Twin>(c => c.DeviceId == twin.DeviceId), It.Is<Concentrator>(c => c.DeviceId == concentrator.DeviceId)));
this.mockLogger.Setup(x => x.Log(It.IsAny<LogLevel>(), It.IsAny<EventId>(), It.IsAny<It.IsAnyType>(), It.IsAny<Exception>(), It.IsAny<Func<It.IsAnyType, Exception, string>>()));

// Act
var result = await concentratorController.CreateDeviceAsync(concentrator);

// Assert
Assert.IsNotNull(result);
Assert.IsAssignableFrom<OkObjectResult>(result);
var okObjectResult = result as ObjectResult;
Assert.IsNotNull(okObjectResult);
Assert.AreEqual(200, okObjectResult.StatusCode);
Assert.IsNotNull(okObjectResult.Value);
Assert.IsAssignableFrom<BulkRegistryOperationResult>(okObjectResult.Value);
Assert.AreEqual(mockResult, okObjectResult.Value);
}

[Test]
public async Task UpdateDeviceAsync_With_Valid_Argument_Should_Return_OkResult()
{
// Arrange
var concentratorController = this.CreateController();
var concentrator = new Concentrator
{
DeviceId = "4512457896451156",
LoraRegion = Guid.NewGuid().ToString(),
IsEnabled = true,
RouterConfig = new RouterConfig()
};

var twin = new Twin
{
DeviceId = concentrator.DeviceId,
};

var device = new Device(concentrator.DeviceId);

this.mockRouterManager.Setup(x => x.GetRouterConfig(It.Is<string>(c => c == concentrator.LoraRegion)))
.ReturnsAsync(concentrator.RouterConfig);
this.mockConcentratorTwinMapper.Setup(x => x.UpdateTwin(It.Is<Twin>(c => c.DeviceId == twin.DeviceId), It.Is<Concentrator>(c => c.DeviceId == concentrator.DeviceId)));

this.mockDeviceService.Setup(x => x.GetDevice(It.Is<string>(c => c == concentrator.DeviceId)))
.ReturnsAsync(device);
this.mockDeviceService.Setup(x => x.UpdateDevice(It.Is<Device>(c => c.Id == concentrator.DeviceId)))
.ReturnsAsync(device);
this.mockDeviceService.Setup(x => x.GetDeviceTwin(It.Is<string>(c => c == concentrator.DeviceId)))
.ReturnsAsync(twin);
this.mockDeviceService.Setup(x => x.UpdateDeviceTwin(It.Is<string>(c => c == concentrator.DeviceId), It.Is<Twin>(c => c.DeviceId == concentrator.DeviceId)))
.ReturnsAsync(twin);

// Act
var result = await concentratorController.UpdateDeviceAsync(concentrator);

// Assert
Assert.IsNotNull(result);
Assert.IsAssignableFrom<OkObjectResult>(result);
var okObjectResult = result as ObjectResult;
Assert.IsNotNull(okObjectResult);
Assert.AreEqual(200, okObjectResult.StatusCode);
}

[Test]
public async Task DeleteDeviceAsync()
{
await Task.CompletedTask;
Assert.Inconclusive();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
using System.Threading.Tasks;
using static AzureIoTHub.Portal.Server.Startup;

namespace AzureIoTHub.Portal.Server.Tests.Controllers.v10.LoRaWAN
namespace AzureIoTHub.Portal.Server.Tests.Controllers.V10.LoRaWAN
{
[TestFixture]
public class LoRaWANConcentratorsControllerTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
using System.Threading;
using System.Threading.Tasks;

namespace AzureIoTHub.Portal.Server.Tests.Controllers.v10.LoRaWAN
namespace AzureIoTHub.Portal.Server.Tests.Controllers.V10.LoRaWAN
{
[TestFixture]
public class LoRaWANDevicesControllerTests
Expand Down
50 changes: 50 additions & 0 deletions src/AzureIoTHub.Portal.Server.Tests.Unit/Helpers/MockHttpHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Bunit;
using Microsoft.Extensions.DependencyInjection;
using RichardSzalay.MockHttp;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;

namespace AzureIoTHub.Portal.Server.Tests.Unit.Helpers
{
public static class MockHttpHelper
{
public static MockHttpMessageHandler AddMockHttpClient(this TestServiceProvider services)
{
var mockHttpHandler = new MockHttpMessageHandler();
var httpClient = mockHttpHandler.ToHttpClient();
httpClient.BaseAddress = new Uri("http://fake.local");
services.AddSingleton<HttpClient>(httpClient);

return mockHttpHandler;
}

public static MockedRequest RespondJson<T>(this MockedRequest request, T content)
{
request.Respond(req =>
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(JsonSerializer.Serialize(content));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return response;
});

return request;
}

public static MockedRequest RespondJson<T>(this MockedRequest request, Func<T> contentProvider)
{
request.Respond(req =>
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(JsonSerializer.Serialize(contentProvider()));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return response;
});

return request;
}
}
}
Loading

0 comments on commit b9fdcdf

Please sign in to comment.