2016-03-26 7 views
-1
interface ITest 
{ 
    void Run(); 
} 

class Test : ITest 
{ 
    void ITest.Run() => Run(); 
    public int Run() 
    { 
     //... 
    } 
} 

Здравствуйте, как проверить, что ITest.Run() выполнил «Запуск» теста?Как протестировать метод интерфейса

+0

Вы можете использовать возвращаемое значение 'Run', или вы можете что-то напечатать, вы можете отлаживать ... есть несколько способов сделать это ... – Ian

+0

Я хочу сделать что-нибудь вроде mock.Verify (m => m.Run(), Times.Once()); Но я не понимаю, как я могу это сделать. – Serg046

+0

Это зависит от насмешливой структуры, которую вы используете. Итак, можете ли вы указать, что вы сейчас используете? –

ответ

0

Не имеет смысла проверять, что Run вызывается, если ваш интерфейс не используется в другом классе. (а не класс, реализующий его). Так что если у вас есть второй класс, используя свой ITEST-интерфейс, то имеет смысл проверить, что Run называются, как вы сделали

+0

Я тестирую тестовый класс (не интерфейс ITest) – Serg046

1

Вы могли тест это с помощью насмешливых рамок как Moq:

public interface ITest 
{ 
    void Run(); 
} 

public class Test : ITest 
{ 
    void ITest.Run() => Run(); 

    public virtual int Run() 
    { 
     return 1; // doesn’t matter, will be replaced by our mock 
    } 
} 

тест будет выглядеть следующим образом:

// arrange 
Mock<Test> mock = new Mock<Test>(); 
mock.CallBase = true; 
mock.Setup(t => t.Run()).Returns(1); 

// act 
ITest test = mock.Object; 
test.Run(); 

// assert 
mock.Verify(t => t.Run(), Times.Once()); 

Это правильно бросает, когда ITest.Run не вызывает Run из Test. Однако, как вы можете видеть, для этого требуется, чтобы метод Run был виртуальным, чтобы макет мог перезаписать его своей собственной реализацией. Это может быть нежелательно.

И, в конечном счете, этот тест не имеет никакого смысла. Когда вы что-то тестируете, вы хотите, чтобы блок тестировал поведение , а не реализацию. Поэтому для вас не имеет значения, вызывает ли явная реализация ITest.Run другой метод для объекта. Вы должны только заботиться о том, чтобы поведение вызова этого метода было правильным.

+0

Спасибо за mock.CallBase = true ... – Serg046

+0

Но я не могу сделать метод Run как виртуальный – Serg046

+0

@ Serg046 Как я объяснил в своем ответе, нет способа протестировать метод * '' Test '* класса, не делая его виртуальным в этом случае, поскольку в противном случае макет не может его переопределить. Обратите внимание, что принятый ответ вообще не тестирует класс 'Test', но проверяет только интерфейс (и на самом деле только те тесты, которые макет, который реализует интерфейс, вызывает метод при вызове метода). – poke

1

Проверка интерфейса - это самая простая задача! Вы просто можете сделать это с Typemock Isolator (без виртуальных методов, необходимых), посмотрите:

[TestMethod, Isolated] 
public void TestRun() 
{ 
    //Arrange 
    var fake = Isolate.Fake.Instance<ITest>(); 
    Isolate.WhenCalled(() => fake.Run()).CallOriginal(); 

    //Act 
    fake.Run(); 

    //Assert 
    Isolate.Verify.WasCalledWithAnyArguments(() => fake.Run()); 
} 

Вы насмехаясь интерфейс, а затем установить поведение Run() метод (это необязательно), и в конце концов вы может подтвердить, что звонок был выполнен.

Надеюсь, это поможет!

+1

Это не делает ничего полезного. Вы предоставляете фальшивую/макетную реализацию интерфейса, вызываете метод интерфейса, а затем проверяете, был ли этот точный метод вызван (что вы явно сделали в тесте). Это не проверяет класс «Тест» OP вообще. – poke

Смежные вопросы