2015-06-30 2 views
6

Можно проверить, вызван ли метод с использованием Moq and dependency injection. Однако можно ли проверить, что один метод в классе вызывает другого в одном классе?Тестирование, если метод в классе А был вызван из другого метода в ClassA

Например, я хочу проверить, что если я регистрирую какое-то исключение, также регистрируется информационное сообщение.

Метод:

public void Error(string message, Exception exception, long logId = 0) 
{ 
    var int32 = (int)logId; 
    Info("Id was converted to an int so that it would fit in the log: " + logId, int32); 
    Error(message, exception, int32); 
} 

Это была моя попытка модульного тестирования его. Тест не проходит, есть ли способ, которым это можно сделать?

void logging_an_error_with_a_long_id_also_logs_info() 
{ 
    var mock = new Mock<ILogger>(); 
    var testedClass = new Logger(); 
    var counter = 0; 

    testedClass.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue); 

    mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>())); 
} 

Поскольку Info и Error методы в одном классе (CLASSA), я не верю, что я могу передать CLASSA как зависимость в ClassA. Так что он не нуждается в проверке?

+0

Посмотрите [здесь] (http://stackoverflow.com/questions/1417048/how-to-verify-another-method-in-the-class-was-called-using-moq). – dee

ответ

7

Лучшее, что вы можете сделать, это сделать Infovirtual. Это позволит вам создать Mock<Logger>, установить CallBase = true и убедиться, что был вызван Info.

var mock = new Mock<Logger> 
{ 
    CallBase = true 
}; 

mock.Object.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue); 

mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>())); 

Таким образом, вы по-прежнему вызывая фактическую реализацию Error, но вы использовали Moq для проверки Info метод был вызван.

+0

+1 это работает, когда Mock используется, потому что нужен настоящий класс. Не работает для интерфейса Mock . – dee

5

Похоже, вы пытаетесь проверить неправильную вещь. Не важно, что метод Info на вашем классе вызывается из метода Error. Важно то, что происходит поведение метода Info. Как это происходит, это деталь реализации этого класса.

Если бы я был математический класс с двумя функциями:

public int Mult(int x, int y) { 
    return x*y; 
} 

public int Sqr(int x) { 
    return Mult(x,y); 
} 

Я бы не проверить, что вызов Sqr обнаруживаемых функции Mult, я бы проверить Sqr(4)==16. Не имеет значения, выполняется ли это вычисление в методе Sqr или в другом методе класса.

В то время как @ Andrew's solution, вероятно, то, что вам нужно, насмехаясь над классом, который вы тестируете, ведет к плотно связанным, хрупким испытаниям.

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

+0

Легче сказать, что, вероятно, лучший способ, чем обеспечить лучший способ. – Hoppe

+0

@Hoppe. Хотя это правда, для обеспечения лучшего способа часто требуется больше контекста, чем предусмотрено (например, я понятия не имею, какое содержимое вашего Методы ошибок или информации). Иногда лучшее, что можно сделать, это указать альтернативное направление, которое в некоторых откроет дверь, которая позволит им смотреть на свою проблему по-другому. – forsvarir