Прохождение юнит теста C#

Дан юнит тест, который нужно проанализировать и пройти.

[TestCase("07K4M1DZ-BZ", '7', '4', 'Z')]
[TestCase("19K06M1DI-AZ", '9', '6', 'I')]
[TestCase("31K008M1DJ-KZ", '1', '8', 'J')]
public void GetSpecialCodes(string serialNumber, char expectedCode1, char expectedCode2, char expectedCode3)
{
    // Act
    UsingIndexer.GetSpecialCodes(serialNumber, out char code1, out char code2, out char code3);
 
    // Assert
    Assert.That(expectedCode1, Is.EqualTo(code1));
    Assert.That(expectedCode2, Is.EqualTo(code2));
    Assert.That(expectedCode3, Is.EqualTo(code3));
}

Вроде бы все просто: первый должен возвращать 7 (второй элемент), второй должен возвращать 6 (пятый элемент), третий должен возвращать J (10 элемент) Пробуем реализовать данный метод

public static void GetSpecialCodes(string serialNumber, out char expectedCode1, out char expectedCode2, out char expectedCode3)
{
    ArgumentNullException.ThrowIfNull(serialNumber);
 
    expectedCode1 = serialNumber[1];  // Второй символ
    expectedCode2 = serialNumber[5];  // Шестой символ
    expectedCode3 = serialNumber[9];  // Десятый символ
}

В результате тестирования проходит только третий тест и результаты тестирования очень странные (прикрепляю скриншот) введите сюда описание изображения Первый тест:

[TestCase("07K4M1DZ-BZ", '7', '4', 'Z')]
Assert.That(expectedCode2, Is.EqualTo(code2))
Expected: '1'
But was: '4'
Второй тест: [TestCase("19K06M1DI-AZ", '9', '6', 'I')]
Assert.That(expectedCode2, Is.EqualTo(code2))
Expected: 'M'
But was: '6'

Непонятные ожидаемые значения и почему и там и там code2, а не 1???

Если поменять любую строку из метода - все тесты будут неверными и ожидаемые значения станут другими. Что не так с этим тестом, или я просто где-то делаю синтаксическую ошибку


Ответы (2 шт):

Автор решения: aepot

Что странного? Внимательнее на строки посмотрите. И какой там пятый символ.

Очевидно, надо игнорировать нули.

Самое простое, это опираться на индексы соседних символов.

public static void GetSpecialCodes(string serialNumber, out char code1, out char code2, out char code3)
{
    code1 = serialNumber[1]; // serialNumber.IndexOf('K') - 1
    code2 = serialNumber[serialNumber.IndexOf('M') - 1];
    code3 = serialNumber[serialNumber.IndexOf('-') - 1];
}
→ Ссылка
Автор решения: Алексей

Разобрался как это работает. Чтобы закрепить нужно пройти еще 1 тест

[TestCase("P2W12P1937A", "W", "12", "1937", "A")]
[TestCase("P02K13P8732D", "K", "13", "8732", "D")]
[TestCase("P002Z14P3573B", "Z", "14", "3573", "B")]
public void GetSerialNumberDetails(string serialNumber, string expectedCountryCode, string expectedManufacturerCode, string expectedFactoryCode, string expectedStationCode)
{
    // Act
    UsingRanges.GetSerialNumberDetails(serialNumber, out string countryCode, out string manufacturerCode, out string factoryCode, out string stationCode);

    // Assert
    Assert.That(expectedCountryCode, Is.EqualTo(countryCode));
    Assert.That(expectedManufacturerCode, Is.EqualTo(manufacturerCode));
    Assert.That(expectedFactoryCode, Is.EqualTo(factoryCode));
    Assert.That(expectedStationCode, Is.EqualTo(stationCode));
}

Тут мы видим, что (expectedCountryCode) находится сразу после "2". expectedCountryCode находится перед "P" (два символа). expectedFactoryCode - 5-2 символ с конца. И expectedStationCode последний символ. Но моя реализация почему-то не проходит.

public static void GetSerialNumberDetails(string serialNumber, out string countryCode, out string manufacturerCode, out string factoryCode, out string stationCode)
{
     ArgumentNullException.ThrowIfNull(serialNumber);

     string manufacturerCode1 = serialNumber[serialNumber.IndexOf('P', StringComparison.Ordinal) - 2].ToString();
     string manufacturerCode2 = serialNumber[serialNumber.IndexOf('P', StringComparison.Ordinal) - 1].ToString();

     countryCode = serialNumber[serialNumber.IndexOf('2', StringComparison.Ordinal) + 1].ToString();
     manufacturerCode = manufacturerCode1 + manufacturerCode2;
     factoryCode = serialNumber[^5..^2].ToString();
     stationCode = serialNumber[^1].ToString();
}

Извиняюсь, за то, что криво выделил вызов метода, что-то стэковерфлоу не дает. Знаю что криво ищу manufacturerCode, но оно вроде правильно выглядит

→ Ссылка