2016-12-30 8 views
0

Хорошо, я спросил это:Интервью Q: Использование Moq для проверки исключения, вызванного без интерфейсов?

Учитывая этот класс

public class ModelWrapper 
{ 
    private Customer _customer;    // Entity Framework POCO model 

    public ModelWrapper(Customer model) 
    { 
     if (model == null) 
      throw new ArgumentNullException("model"); 

     _customer = model; 
    } 
} 

Написать модульное тестирование с помощью Moq для тестирования The ArugmentNullException выбрасывается при переходе в нуль параметра. Примечание: Вам не нужно реализовать интерфейс

Хорошо, так что я думал, что будет работать было бы что-то подобное в XUnit:

[Fact] 
public void ShouldTestArgumentNullException() 
{ 
    var test = Assert.Throws<ArgumentNullException>(
     new ModelWrapper(null) 
    ); 

    Assert.Equal(test.ParamName,"model"); 
} 

И даже если это работает, это WASN» Правильный ответ. Затем я попытался это:

_mock.Setup(w => new ModelWrapper(null)).Throws(new ArgumentNullException("model")); 
_mock.Verify(); 

, которые не работают, и я получил это исключение вместо:

Сообщение: System.ArgumentException: Expression не является вызов метода: ш => новый ModelWrapper (null)

Итак, что такое правильный ответ?

EDIT UPDATE: Мне сказали, что я могу использовать только конкретный класс в Moq, что-то вроде этого:

var _mock = new Mock<ModelWrapper>(); 

Но, я все еще не в состоянии понять, как это может быть сделано. Как вы видите, когда я написал код, используя конкретный класс ModelWrapper, он все равно не удался.

+3

Может быть, лучше задать вопрос здесь http://codereview.stackexchange.com – Flexicoder

+3

Я не вижу, как здесь можно использовать Moq. Это просто. Вызовите 'new ModelWrapper (null);' и убедитесь, что исключение было выбрано через соответствующую тестовую среду (MSTest/xUnit/whatever). – nvoigt

+5

Я голосую, чтобы закрыть этот вопрос как не по теме, потому что мы не можем читать ваши потенциальные мысли будущих работодателей. Технически, Moq не требуется для написания совершенно правильного модульного теста. – nvoigt

ответ

6

Это вполне хороший тест, используя только то, что Visual Studio дает нам:

[TestMethod] 
[ExpectedException(typeof(ArgumentNullException))] 
public void ModelWrapperThrowsOnNullModel() 
{ 
    new ModelWrapper(null); 
} 

Теперь Вы можете добавить все виды сторонних библиотек, но предполагаю, что ваш потенциальный будущий работодатель, возможно, хотел бы видеть за пределами объем технической экспертизы. Нет причин издеваться над чем-либо, поэтому необходимость использования Moq (или подобных библиотек) для этой задачи является искусственным требованием, которое существует только в голове интервьюера.

+0

Это именно то, о чем я думал, а так как xUnit делает что-то подобное, и это упражнение в бесполезности , Я думал, что это был ответ, используя xUnit, так как я могу уйти с несколькими строками кода, но это не так. Интервьюер дал высокую оценку за то, что он сделал что-то подобное в xUnit, увидев, что другие кандидаты даже не могли придумать что-то вроде этого! Мало того, что я придумал единичный тест для проверки исключения, я также проверил имя параметра (см. Конструктор, он выдает ParamName как «модель») –

0

Я согласен с тем, что использование Moq здесь совершенно не нужно и отвечает на ответ nvoigt.

Сказанное, учитывая, что они хотят, чтобы вы использовали moq, все равно это может быть сделано, что кажется для меня чем-то вроде взлома.

[TestClass] 
public class MoqVerifyExceptionWithoutInterface { 
    [TestMethod] 
    [ExpectedException(typeof(ArgumentNullException))] 
    public void ModelWrapperThrowsOnNullModel() { 
     var mock = new Mock<ModelWrapper>(MockBehavior.Strict, null); 
     try { 
      var model = mock.Object; 
     } catch (TargetInvocationException e) { 
      if (e.InnerException != null) 
       throw e.InnerException; 
      throw; 
     } 
    } 

    public class ModelWrapper { 
     private Customer _customer; 
     public ModelWrapper(Customer model) { 
      if (model == null) 
       throw new ArgumentNullException("model"); 
      _customer = model; 
     } 
    } 

    public class Customer { } 
}