Как создать unittest для функции, использующей JwtEncoder?

#c# #unit-testing #encoding

#c# #модульное тестирование #кодирование

Вопрос:

Я использую этот код для создания токена авторизации.

  public string Get(string tenantId, string appId, string appSecret)
{
    const int TimeoutSecs = 1800;
    var tool = new MyDateTimeTool();
    var unixTime = tool.ToUnixTimestamp(m_dateTime);
    var unixTimeExpires = tool.ToUnixTimestamp(m_dateTime.UtcNow.AddSeconds(TimeoutSecs));
    var jwtClaims = new JwtClaims
    {
        jti = Guid.NewGuid().ToString(),
        iat = unixTime,
        exp = unixTimeExpires,
        iss = "http://cylance.com",
        tid = tenantId,
        sub = appId
    };

    var algorithm = new HMACSHA256Algorithm();
    var serializer = new JsonNetSerializer();
    var encoder = new  JwtBase64UrlEncoder();
    var jwt = new JwtEncoder(algorithm, serializer, encoder);

    return jwt.Encode(jwtClaims, appSecret);
}
  

Итак, я хочу создать unittest для этой функции. Этот unittest выглядит следующим образом:

 string tenantId = "ThisIsATennantId";
string appId = "ThisIsAnAppID";
string appSecret = "ThisIsASecret";
IMyDateTime dateTime = new FakeMyDateTime("17.7.2019 17:22:45");
IAuthorizationTokenGetter getter = new AuthorizationTokenGetter(dateTime);
string token = getter.Get(tenantId,appId,appSecret);
Assert.Equal(token, "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjMzNzg3NjUsImlhdCI6MTU2MzM3Njk2NSwiaXNzIjoiaHR0cDovL2N5bGFuY2UuY29tIiwic3ViIjoiRGFzaXN0ZWluZUFwcElEazk4Nzk4aCIsImp0aSI6ImM2MTZjYzFhLTQ2MDUtNGQzNi1hNDBmLTVjZDQ1YjliNzNjMiIsInRpZCI6IkRhc2lzdGVpbmVUZW5uYW50SUQ4OTkwOGdqZ21tbm4ifQ.kzyTnLKykCA_fKuSOMxaS7SwYkB-08pVcNZeABZSq_E"); 
  

Но токен всегда отличается. Поэтому я думаю, что кодировщик использует рандомизатор или внутреннее системное время.

Итак, есть ли способ указать кодировщику использовать специальное начальное значение или время, чтобы он выдавал детерминированные результаты? Или мне нужно создать контейнер для JwtEncoder, чтобы я мог подделать результаты?

Комментарии:

1. Get Метод использует Guid.NewGuid() . Конечно, каждый раз значение будет новым.

2. Вы также создаете и используете time . Предположительно, его значение также каждый раз отличается.

3. @Александр Петров: Вы правы. Guid. NewGuid() — это то, что я должен подделать. Но время как «m_dateTime» уже подделано (см.: new FakeMyDateTime(«17.7.2019 17:22:45»)).

Ответ №1:

Проблема заключалась не в кодировщике, а в создании идентификатора Guid. Итак, я создал контейнер для создания Guid, чтобы я мог подделать и это. Теперь unittest выглядит так:

 string tenantId = "DasisteineTennantID89908gjgmmnn";
string appId = "DasisteineAppIDk98798h";
string appSecret = "DasisteinAppSecret899ahiuhri78789";
IMyDateTime dateTime = new FakeMyDateTime("17.7.2019 17:22:45");
IMyGUIDFactory guidFactory = new FakeMyGUIDFactory("0f889994-f4ea-4db3-9ee3-af40b8313768");
IAuthorizationTokenGetter getter = new AuthorizationTokenGetter(dateTime, guidFactory);
string token = getter.Get(tenantId,appId,appSecret);
Assert.Gleich(token, "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjMzNzg3NjUsImlhdCI6MTU2MzM3Njk2NSwiaXNzIjoiaHR0cDovL2N5bGFuY2UuY29tIiwic3ViIjoiRGFzaXN0ZWluZUFwcElEazk4Nzk4aCIsImp0aSI6IjBmODg5OTk0LWY0ZWEtNGRiMy05ZWUzLWFmNDBiODMxMzc2OCIsInRpZCI6IkRhc2lzdGVpbmVUZW5uYW50SUQ4OTkwOGdqZ21tbm4ifQ.SwkjfpdpHDM1EG1xNVIXaNBrvRVd3wWXr0HLFlJpLSk");