2015-10-20 45 views
2

我已经创建了一些抽象方法的抽象基类叫做:验证,如果一个抽象的方法是使用最小起订量

public abstract class MyBaseClass<T> where T: class, IEntity 
{ 

    public T Load(long id) 
    { 
    //if in cache continue with cached value 
    //else make use of protected abstract LoadFromContext 
    } 

    protected abstract T LoadFromContext(long id); 
} 

现在我要检查,如果LoadFromContext我们调用,但我得到一个错误:System.ArgumentException :成员FakeCacheRepository.LoadFromContext不存在

单元测试Moq的Setup其中FakeCacheRepository是派生型的MyBaseClass:

Mock<FakeCacheRepository> personRepoMock = new Mock<FakeCacheRepository>(); 
personRepoMock.Setup(x => x.Load(14)).Returns(new Person() { ID = 14, Name = "Developer14" }); 
personRepoMock.Protected().Setup("LoadFromContext"); 

var person = new FakeCacheRepository().Load(14); 

Assert.AreEqual("Developer14", person.Name); 
personRepoMock.Protected().Verify("LoadFromContext", Times.Once()); 

我做错了什么,是否有任何关于moq的好教程,以便更好地理解,而不必去Google提出每个问题。

回答

3

您设置的模拟对象personRepoMock似乎没有被FakeCacheRepository对象person使用。所以你的设置和验证不被使用。

但是,我不认为这是测试这个的正确方法,我只是在不嘲笑的情况下测试FakeCacheRepository类。从外部看,FakeCacheRepository继承自MyBaseClass并不重要,因此只需测试FakeCacheRepository公开的方法。

如果您想要在多个类之间共享代码,请将该代码提取到单独的类中 - 继承不应该用于共享代码。

+0

嗨汤姆,不想在这里开始讨论如何构建代码。在代码应该被提取时,我应该如何继承代码,哪里可以找到指导原则?这里讨论的基类正式名称为“CachedRepositoryBase”...所有缓存内容都放在这里。只有连接特定的东西放在继承的类中,仍然是缓存的存储库类(如此继承)。目前这似乎对我而言是合法的。 –

+0

我没有任何特定的发送链接,但Google的一句“编写可测试代码”的短语引出了不少可能引起您关注的文章。 – TomDoesCode

4

除了什么TomDoesCode已经说过:

要使用Protected()你的方式,你必须使用通用的版本,因为LoadFromContext返回一个值(Person)。此外,你必须传递参数:

personRepoMock.Protected().Setup<Person>("LoadFromContext", 14L); 

同样,你Verify有看起来像

personRepoMock.Protected().Verify<Person>("LoadFromContext", Times.Once(), 14L); 

但是,即使你会改变这种状况,你的测试是行不通的。你创建一个FakeCacheRepository的模拟,但是然后在FakeCacheRepository的新实例上调用Load(14),而不是在模拟上。

你应该退后一步,想想你想要测试的是什么。如果你想测试FakeCacheRepository是否从Load调用LoadFromContext,那么moq不是适合这项工作的工具。

+0

如果从Load调用“LoadFromContext”,测试还有其他什么选项?除手动调试外。我是单元测试新手,但我看到了可能性和优势。当知道测试是正确的方法时,不想停止。 –

+0

如果你真的想测试一下,你可以创建一个'MyBaseClass'的子类,它简单地在'LoadFromContext'中设置一个标志,并在调用'Load'后检查该标志是否用简单的'Assert'设置。如果您现在将您在代码中写入的缓存抽象出来,那么您还可以测试在使用缓存的情况下是否调用了“LoadFromContext”。 – sloth