简体   繁体   English

Docker 组合 .Net Core NUnit 测试和 Redis

[英]Docker compose .Net Core NUnit Test and Redis

I have a .Net Core solution containing an API and the NUnit test.我有一个包含 API 和 NUnit 测试的 .Net Core 解决方案。 When I run docker-compose up the API works fine if I don't include the test.当我运行docker-compose up ,如果我不包含测试,API 就可以正常工作。 However if I implement the test then docker compose cannot build, with the error StackExchange.Redis.RedisConnectionException : It was not possible to connect to the redis server(s). UnableToConnect on redis-service:6379/Interactive但是,如果我实施测试,则 docker compose 无法构建,并出现错误StackExchange.Redis.RedisConnectionException : It was not possible to connect to the redis server(s). UnableToConnect on redis-service:6379/Interactive StackExchange.Redis.RedisConnectionException : It was not possible to connect to the redis server(s). UnableToConnect on redis-service:6379/Interactive in command line. StackExchange.Redis.RedisConnectionException : It was not possible to connect to the redis server(s). UnableToConnect on redis-service:6379/Interactive in command line。

My Dockerfile :我的Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["ReportApi/ReportApi.csproj", "ReportApi/"]
COPY ["ReportApi.Test/ReportApi.Test.csproj", "ReportApi.Test/"]RUN dotnet restore "ReportApi/ReportApi.csproj"
RUN dotnet restore "ReportApi.Test/ReportApi.Test.csproj"
COPY . .
WORKDIR "/src/ReportApi"
RUN dotnet build "ReportApi.csproj" -c Release -o /app/build
WORKDIR "/src/ReportApi.Test"
RUN dotnet build "ReportApi.Test.csproj" -c Release -o /app/build


FROM build AS publish
WORKDIR "/src/ReportApi"
RUN dotnet publish "ReportApi.csproj" -c Release -o /app/publish
WORKDIR "/src/ReportApi.Test"
RUN dotnet test "ReportApi.Test.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ReportApi.dll"]

My docker-compose.yml :docker-compose.yml

version: "3.7"
services: 
    redis-service:
        container_name: redis
        image: redis
        ports:
            - "6379:6379"
        restart: always

    report-api:
        build: 
            context: .
            dockerfile: Dockerfile
        ports: 
            - "10001:80"
        depends_on: 
            - "redis-service"

My test class:我的测试班:

namespace ReportApi.Test
{
    class RedisCacheControllerTest
    {
        public IDatabase Cache { get; set; }
        public RedisCacheController Controller { get; set; }

        [SetUp]
        public void Init()
        {

            // Set up Redis Cache
            var redis = ConnectionMultiplexer.Connect("redis-service:6379");

            var services = new ServiceCollection();
            services.AddScoped(s => redis.GetDatabase());
            var provider = services.BuildServiceProvider();
            Cache = provider.GetService<IDatabase>();

            // Create controller instance
            Controller = new RedisCacheController(Cache);

        }

        [Test]
        public void InsertRecordTest()
        {
            // Create a new instance of RedisCache
            RedisCache redisCache = new RedisCache()
            {
                id = "testId",
                value = "CacheData"
            };

            // If the redisCache object doesn't exist, check if it returns 200 OK;
            // otherwise check if it returns 409 Conflict
            if (Cache.StringGet(redisCache.id).Length() == 0)
            {
                Assert.IsInstanceOf<OkObjectResult>(Controller.Create(redisCache));
            }
            else
            {
                Assert.IsInstanceOf<ConflictObjectResult>(Controller.Create(redisCache));
            }
        }

        [Test]
        public void RetrieveRecordTest()
        {
            string key = "testId";
            // If the record exists, check if it returns 200 OK;
            // otherwise check if it returns 204 No Content
            if (Cache.StringGet(key).Length() != 0)
            {
                Assert.IsInstanceOf<OkObjectResult>(Controller.Get(key));
            }
            else
            {
                Assert.IsInstanceOf<NoContentResult>(Controller.Get(key));
            }
        }
    }
}

Redis is defined in docker-compose.yml, which will run only when every service (defined in it) has been built already. Redis 在 docker-compose.yml 中定义,只有在每个服务(在其中定义)都已经构建后才会运行。

Thus, at the moment of building your Dockerfile, nothing yet has been run from docker-compose.因此,在构建 Dockerfile 时,还没有从 docker-compose 运行任何内容。

Over internet people recomend in such situations different approaches, for example: https://medium.com/@christiansparre/integration-testing-with-docker-compose-and-visual-studio-team-service-83a1166055a8在这种情况下,人们通过互联网推荐不同的方法,例如: https : //medium.com/@christiansparre/integration-testing-with-docker-compose-and-visual-studio-team-service-83a1166055a8

But, anyway, I would recomend you not to run tests at the moment of building the Dockerfile.但是,无论如何,我建议您不要在构建 Dockerfile 时运行测试。 Instead, run them from your docker-compose.yml (link above).相反,从您的 docker-compose.yml(上面的链接)运行它们。

The goal of the approach you are using currently is to ensure, that image of your container is already tested at the moment of creation.您当前使用的方法的目标是确保您的容器映像在创建时已经过测试。 But, you don't have points from that.但是,你没有积分。 If your tests failed after image has been built already, just delete and don't use it, nobody requires you to run keep the container if it does not work.如果您的测试在镜像构建后失败,只需删除并不要使用它,如果容器不起作用,没有人要求您运行保持容器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM