Использовать класс в inlineData теста - PullRequest
0 голосов
/ 07 октября 2019

В качестве класса Mocked я использовал следующий класс:

public class MockData
{
    public static MockData Current { get; } = new MockData();
    public List<ClientViewModel> Choices { get; set; }

    public MockData()
    {
        Choices = new List<ClientViewModel>
        {
            new ClientViewModel { Answers = new[] { false, false, false } },
            new ClientViewModel { Answers = new[] { true, true, true } },
            new ClientViewModel { Answers = new[] { true, true, false } },
            new ClientViewModel { Answers = new[] { true, false, true } },
            new ClientViewModel { Answers = new[] { true, false, false } }
        };
    }
}

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

[Fact]
public void ClientRequest_UserChoicesPassed_ReturnsRightAnswer()
{
    // Arrange
    var clientViewModel = MockData.Current.Choices[0];

    // Act
    var jsonResult = _controller.ClientRequest(clientViewModel) as JsonResult;

    // Assert
    string expectedAnswer = "It is a book";
    Assert.Equal(expectedAnswer, ((ResultDTO)jsonResult.Value).Result);
}

Это работает отлично, и мой тест пройден, как и ожидалось. Однако моя проблема с этим подходом состоит в том, что я должен повторить этот тест и для других записей, как вы заметили, я использовал var clientViewModel = MockData.Current.Choices[0]; в разделе Arrange теста, чтобы проверить первую запись, я не хочуповторить себя, написав несколько тестов для этой цели. Я уже знаком с понятиями [Theory] и [InlineData] в xNunit, однако, похоже, у меня есть некоторые трудности с классом, см. Ниже:

[Theory]
[InlineData(MockData.Current.Choices[0], "It is a book")]
[InlineData(MockData.Current.Choices[1], "It is a pen")]
public void ClientRequest_UserChoicesPassed_ReturnsRightAnswer(ClientViewModel clientViewModel, string expectedAnswer)
{
  //...
}

Но это дает мне следующее исключение:

Аргумент атрибута должен быть константным выражением, выражением typeof или выражением создания массива типа параметра атрибута

Поэтому, пожалуйста, дайте мне знать, есть ли способ, я могу сделать что-нибудьпредотвратить повторение этого метода?

1 Ответ

4 голосов
/ 07 октября 2019

Для этого вы можете использовать MemberDataAttribute с открытым статическим методом, который возвращает ваши тестовые примеры, которые будут использоваться. Вот пример:

public static IEnumerable<object[]> GetUserChoiceTestData() 
{
    yield return new object[] { MockData.Current.Choices[0], "It is a book" };
    yield return new object[] { MockData.Current.Choices[1], "It is a pen" };
}

Который вы затем примените к своей теории теста следующим образом:

[Theory]
[MemberData(nameof(GetUserChoiceTestData))]
public void ClientRequest_UserChoicesPassed_ReturnsRightAnswer(ClientViewModel clientViewModel, string expectedAnswer)
{
  //...
}

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

[MemberData(nameof(SomeOtherClass.GetUserChoiceTestData), MemberType = typeof(SomeOtherClass))]
...